c# - सी#की छिपी हुई विशेषताएं?




hidden-features (20)

इस प्रश्न से निम्नलिखित जानने के बाद यह मेरे दिमाग में आया:

where T : struct

हम, सी # डेवलपर्स, सभी सी # की मूल बातें जानते हैं। मेरा मतलब है घोषणाएं, सशर्त, लूप, ऑपरेटर इत्यादि।

हम में से कुछ ने Generics , गुमनाम प्रकार , lambdas , LINQ , जैसे सामानों को भी महारत हासिल किया ...

लेकिन सी # की सबसे छिपी हुई विशेषताएं या चाल क्या हैं कि सी # प्रशंसकों, नशेड़ी, विशेषज्ञों को मुश्किल से पता है?

यहां तक ​​कि अब तक बताई गई विशेषताएं हैं:


कीवर्ड

गुण

वाक्य - विन्यास

  • ?? kokos द्वारा (coalesce nulls) ऑपरेटर
  • निक बर्र्डी द्वारा संख्या ध्वज
  • where T:new लार्स माइलम द्वारा where T:new
  • Keith द्वारा लागू Keith
  • Keith द्वारा एक पैरामीटर लैम्बडास
  • Keith द्वारा ऑटो गुण
  • Keith द्वारा नेमस्पेस उपनाम
  • Patrick द्वारा @ के साथ Verbatim स्ट्रिंग अक्षर
  • lfoust द्वारा enum मूल्य
  • मार्क्सिडाड द्वारा marxidad
  • marxidad द्वारा event ऑपरेटर
  • Portman द्वारा प्रारूप स्ट्रिंग ब्रैकेट्स
  • xanadont द्वारा संपत्ति xanadont अभिगम्यता modifiers
  • JasonS द्वारा सशर्त (टर्नरी) ऑपरेटर ( ?: JasonS
  • बिनोज एंटनी द्वारा checked और unchecked ऑपरेटर
  • Flory द्वारा implicit and explicit ऑपरेटरों

भाषा सुविधाएं

विजुअल स्टूडियो विशेषताएं

  • Himadri द्वारा संपादक में टेक्स्ट का ब्लॉक चुनें
  • DannySmurf द्वारा स्निपेट्स

ढांचा

तरीके और गुण

  • KiwiBastard द्वारा KiwiBastard String.IsNullOrEmpty() विधि
  • List.ForEach() द्वारा List.ForEach() विधि
  • Will Dean द्वारा BeginInvoke() , EndInvoke() विधियों
  • Nullable<T>.HasValue और Nullable<T>.Value Rismo द्वारा Rismo गुण
  • जॉन GetValueOrDefault द्वारा GetValueOrDefault विधि

सलाह & चाल

  • एंड्रियास एचआर निल्सन द्वारा इवेंट हैंडलर के लिए अच्छी विधि
  • John द्वारा अपरकेस तुलना
  • dp द्वारा प्रतिबिंब के बिना अज्ञात प्रकारों तक पहुंचें
  • Will द्वारा संग्रह संपत्तियों को आलसी ढंग से त्वरित करने का एक त्वरित तरीका
  • roosteronacid द्वारा जावास्क्रिप्ट की तरह अज्ञात इनलाइन-फ़ंक्शन

अन्य

https://code.i-harness.com


@ स्ट्रिंग में किसी भी भागने वाले पात्रों को अनदेखा करने के लिए कंपाइलर को बताता है।

बस इसे स्पष्ट करना चाहता था ... यह बचने वाले पात्रों को अनदेखा करने के लिए नहीं कहता है, यह वास्तव में स्ट्रिंग को एक शाब्दिक के रूप में समझने के लिए संकलक को बताता है।

यदि आपके पास है

string s = @"cat
             dog
             fish"

यह वास्तव में प्रिंट करेगा (ध्यान दें कि इसमें इंडेंटेशन के लिए उपयोग किए जाने वाले व्हाइटस्पेस भी शामिल हैं):

cat
             dog
             fish

सीएलआर से सी # के माध्यम से:

तारों को सामान्यीकृत करते समय, अत्यधिक अनुशंसा की जाती है कि आप ToLowerInvariant के बजाय ToUpperInvariant का उपयोग करें क्योंकि माइक्रोसॉफ्ट ने अपरकेस तुलना करने के लिए कोड को अनुकूलित किया है

मुझे याद है कि एक बार मेरे सहकर्मी ने तुलना करने से पहले स्ट्रिंग्स को अपरकेस में बदल दिया। मैंने हमेशा सोचा है कि वह ऐसा क्यों करता है क्योंकि मुझे लगता है कि पहले इसे लोअरकेस में बदलने के लिए यह "प्राकृतिक" है। पुस्तक पढ़ने के बाद अब मुझे पता है क्यों।


  1. ?? - coalescing operator
  2. using ( statement / directive ) - great keyword that can be used for more than just calling Dispose
  3. readonly - should be used more
  4. netmodules - too bad there's no support in Visual Studio

" yield " मेरे दिमाग में आ जाएगी। DefaultValueAttribute जैसे कुछ विशेषताओं में से मेरे पसंदीदा भी हैं।

" var " कीवर्ड थोड़ा और ज्ञात है, लेकिन आप इसका उपयोग .NET 2.0 अनुप्रयोगों में भी कर सकते हैं (जब तक आप .NET 3.5 कंपाइलर का उपयोग करते हैं और इसे 2.0 कोड आउटपुट पर सेट करते हैं) ऐसा नहीं लगता है कुंआ।

संपादित करें: कोकोस, इंगित करने के लिए धन्यवाद ?? ऑपरेटर, यह वास्तव में वास्तव में उपयोगी है। चूंकि इसके लिए Google के लिए थोड़ा मुश्किल है (जैसा कि ?? केवल अनदेखा किया गया है), यहां उस ऑपरेटर के लिए एमएसडीएन दस्तावेज़ पृष्ठ है : ?? ??


एलियंस जेनरिक:

using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;

यह आपको Dictionary<string, Dictionary<string, List<string>>> बजाय ASimpleName का उपयोग करने की अनुमति देता है।

इसका उपयोग करें जब आप कई जगहों पर एक ही सामान्य बड़ी लंबी जटिल चीज का उपयोग करेंगे।


जेनेरिक प्रकारों में 'डिफ़ॉल्ट' कीवर्ड:

T t = default(T);

परिणाम टी 'नल' में होते हैं यदि टी एक संदर्भ प्रकार है, और 0 यदि यह एक int है, तो झूठी अगर यह एक बुलियन है, आदि।


बाकी सब कुछ, प्लस

1) निहित जेनेरिक (क्यों केवल विधियों पर और वर्गों पर नहीं?)

void GenericMethod<T>( T input ) { ... }

//Infer type, so
GenericMethod<int>(23); //You don't need the <>.
GenericMethod(23);      //Is enough.

2) एक पैरामीटर के साथ सरल lambdas:

x => x.ToString() //simplify so many calls

3) अनाम प्रकार और प्रारंभिक:

//Duck-typed: works with any .Add method.
var colours = new Dictionary<string, string> {
    { "red", "#ff0000" },
    { "green", "#00ff00" },
    { "blue", "#0000ff" }
};

int[] arrayOfInt = { 1, 2, 3, 4, 5 };

और एक:

4) ऑटो गुणों में अलग-अलग स्कोप हो सकते हैं:

public int MyId { get; private set; }

मुझे याद दिलाने के लिए धन्यवाद @pzycoman:

5) नेमस्पेस उपनाम (यह नहीं कि आपको इस विशेष भेद की आवश्यकता है):

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();

मुझे थोड़ी देर के लिए "as" कीवर्ड नहीं पता था।

MyClass myObject = (MyClass) obj;

बनाम

MyClass myObject = obj as MyClass;

दूसरा क्लास कास्ट अपवाद फेंकने के बजाय, ओबीजे माई क्लास नहीं है, तो शून्य वापस आ जाएगा।


मुझे लगता है कि अधिकांश सी # डेवलपर्स को 'शून्य' प्रकार के बारे में पता नहीं है। असल में, प्राइमेटिव्स जिनमें शून्य मूल्य हो सकता है।

double? num1 = null; 
double num2 = num1 ?? -100;

शून्य करने के लिए एक शून्य, num1 , शून्य सेट करें, फिर num1 शून्य होने पर num1 या -100 पर नियमित डबल, num2 सेट करें।

http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

Nullable प्रकार के बारे में एक और बात:

DateTime? tmp = new DateTime();
tmp = null;
return tmp.ToString();

यह वापसी स्ट्रिंग है। लक्षण। अधिक जानकारी के लिए this लिंक को देखें


मुझे लगता है कि सी # (.NET 3.5) की सबसे कम सराहनीय और कम ज्ञात विशेषताओं में से एक अभिव्यक्ति पेड़ हैं , खासकर जब जेनेरिक और लैम्बडास के साथ मिलकर। यह एपीआई सृजन के लिए एक दृष्टिकोण है कि एनइजेक्ट और मोक जैसे नए पुस्तकालयों का उपयोग कर रहे हैं।

उदाहरण के लिए, मान लें कि मैं एक एपीआई के साथ एक विधि पंजीकृत करना चाहता हूं और उस एपीआई को विधि का नाम प्राप्त करने की आवश्यकता है

इस वर्ग को देखते हुए:

public class MyClass
{
     public void SomeMethod() { /* Do Something */ }
}

इससे पहले, डेवलपर्स को तारों और प्रकारों (या कुछ और बड़े पैमाने पर स्ट्रिंग-आधारित) के साथ ऐसा करना बहुत आम था:

RegisterMethod(typeof(MyClass), "SomeMethod");

खैर, वह मजबूत टाइपिंग की कमी के कारण बेकार है। अगर मैं "कुछ विधि" का नाम बदलूं तो क्या होगा? अब, 3.5 में हालांकि, मैं इसे दृढ़ता से टाइप किए गए फैशन में कर सकता हूं:

RegisterMethod<MyClass>(cl => cl.SomeMethod());

जिसमें RegisterMethod क्लास Expression<Action<T>> इस तरह का उपयोग करती है:

void RegisterMethod<T>(Expression<Action<T>> action) where T : class
{
    var expression = (action.Body as MethodCallExpression);

    if (expression != null)
    {
        // TODO: Register method
        Console.WriteLine(expression.Method.Name);
    }
}

यह एक बड़ा कारण है कि मैं अभी लम्बादास और अभिव्यक्ति पेड़ से प्यार करता हूं।


यदि आप अंततः ब्लॉक या FailFast को कॉल किए बिना अपने प्रोग्राम से बाहर निकलना चाहते हैं तो FailFast उपयोग FailFast :

Environment.FailFast()

यह सी # प्रति से नहीं है, लेकिन मैंने किसी ऐसे व्यक्ति को नहीं देखा है जो वास्तव में System.IO.Path.Combine() को उस हद तक उपयोग करता है जो उन्हें करना चाहिए। वास्तव में, संपूर्ण पथ वर्ग वास्तव में उपयोगी है, लेकिन कोई भी इसका उपयोग नहीं करता है!

मैं यह शर्त लगाने के लिए तैयार हूं कि प्रत्येक उत्पादन ऐप में निम्न कोड है, भले ही यह नहीं होना चाहिए:

string path = dir + "\\" + fileName;

रिक स्ट्राल से :

आप चेन कर सकते हैं ?? ऑपरेटर ताकि आप शून्य तुलनाओं का एक गुच्छा कर सकें।

string result = value1 ?? value2 ?? value3 ?? String.Empty;

भेड़ का बच्चा और प्रकार का उल्लंघन कम हो गया है। लैम्बडास में कई कथन हो सकते हैं और वे एक संगत प्रतिनिधि ऑब्जेक्ट के रूप में स्वचालित रूप से दोगुना हो जाते हैं (केवल हस्ताक्षर मिलान सुनिश्चित करें) जैसा कि:

Console.CancelKeyPress +=
    (sender, e) => {
        Console.WriteLine("CTRL+C detected!\n");
        e.Cancel = true;
    };

ध्यान दें कि मेरे पास new CancellationEventHandler नहीं है और न ही मुझे sender प्रकार निर्दिष्ट करना है और e , वे घटना से कमजोर हैं। यही कारण है कि पूरे delegate (blah blah) को लिखना कम बोझिल है, जिसके लिए आपको पैरामीटर के प्रकार निर्दिष्ट करने की भी आवश्यकता होती है।

लैम्ब्डास को कुछ भी वापस करने की आवश्यकता नहीं है और इस तरह के संदर्भ में अनुमान टाइप करना बेहद शक्तिशाली है।

और बीटीडब्लू, आप हमेशा लैम्बडास लौट सकते हैं जो कार्यात्मक प्रोग्रामिंग भावना में लैम्ब्डा बनाते हैं। उदाहरण के लिए, यहां एक लैम्ब्डा है जो एक लैम्ब्डा बनाता है जो बटन को संभालता है। घटना पर क्लिक करें:

Func<int, int, EventHandler> makeHandler =
    (dx, dy) => (sender, e) => {
        var btn = (Button) sender;
        btn.Top += dy;
        btn.Left += dx;
    };

btnUp.Click += makeHandler(0, -1);
btnDown.Click += makeHandler(0, 1);
btnLeft.Click += makeHandler(-1, 0);
btnRight.Click += makeHandler(1, 0);

चेनिंग नोट करें: (dx, dy) => (sender, e) =>

अब यही कारण है कि मैं कार्यात्मक प्रोग्रामिंग कक्षा लेने के लिए खुश हूं :-)

सी में पॉइंटर्स के अलावा, मुझे लगता है कि यह अन्य मौलिक चीज है जिसे आपको सीखना चाहिए :-)


शून्य घटना हैंडलर की जांच से बचें

घोषणाओं पर घटनाओं में एक खाली प्रतिनिधि जोड़ना, इसे कॉल करने से पहले हमेशा शून्य के लिए घटना की जांच करने की ज़रूरत को दबाकर आश्चर्यजनक है। उदाहरण:

public delegate void MyClickHandler(object sender, string myValue);
public event MyClickHandler Click = delegate {}; // add empty delegate!

आपको यह करने दो

public void DoSomething()
{
    Click(this, "foo");
}

इसके अलावा

public void DoSomething()
{
    // Unnecessary!
    MyClickHandler click = Click;
    if (click != null) // Unnecessary! 
    {
        click(this, "foo");
    }
}

कृपया इस विषय पर एरिक लिपर्ट द्वारा इस संबंधित चर्चा और इस ब्लॉग पोस्ट को भी देखें (और संभव डाउनसाइड्स)।


@Ed, I'm a bit reticent about posting this as it's little more than nitpicking. However, I would point out that in your code sample:

MyClass c;
  if (obj is MyClass)
    c = obj as MyClass

If you're going to use 'is', why follow it up with a safe cast using 'as'? If you've ascertained that obj is indeed MyClass, a bog-standard cast:

c = (MyClass)obj

...is never going to fail.

Similarly, you could just say:

MyClass c = obj as MyClass;
if(c != null)
{
   ...
}

I don't know enough about .NET's innards to be sure, but my instincts tell me that this would cut a maximum of two type casts operations down to a maximum of one. It's hardly likely to break the processing bank either way; personally, I think the latter form looks cleaner too.


If you're trying to use curly brackets inside a String.Format expression...

int foo = 3;
string bar = "blind mice";
String.Format("{{I am in brackets!}} {0} {1}", foo, bar);
//Outputs "{I am in brackets!} 3 blind mice"

Maybe not an advanced technique, but one I see all the time that drives me crazy:

if (x == 1)
{
   x = 2;
}
else
{
   x = 3;
}

can be condensed to:

x = (x==1) ? 2 : 3;

Returning anonymous types from a method and accessing members without reflection.

// Useful? probably not.
private void foo()
{
    var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) });
    Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges);
}

object GetUserTuple()
{
    return new { Name = "dp", Badges = 5 };
}    

// Using the magic of Type Inference...
static T AnonCast<T>(object obj, T t)
{
   return (T) obj;
}

This one is not "hidden" so much as it is misnamed.

A lot of attention is paid to the algorithms "map", "reduce", and "filter". What most people don't realize is that .NET 3.5 added all three of these algorithms, but it gave them very SQL-ish names, based on the fact that they're part of LINQ.

"map" => Select
Transforms data from one form into another

"reduce" => Aggregate
Aggregates values into a single result

"filter" => Where
Filters data based on a criteria

The ability to use LINQ to do inline work on collections that used to take iteration and conditionals can be incredibly valuable. It's worth learning how all the LINQ extension methods can help make your code much more compact and maintainable.





hidden-features