hidden-features - الميزات المخفية من C#؟




(25)

يقوم @ بإعلام المحول البرمجي بتجاهل أي أحرف إبطال في سلسلة.

أردت فقط توضيح هذه العبارة ... لا تخبرها بتجاهل أحرف الهروب ، بل إنها تخبر المحول البرمجي أن يفسر السلسلة على أنها حرفية.

اذا كنت تمتلك

string s = @"cat
             dog
             fish"

ستتم طباعتها بالفعل (لاحظ أنها تتضمن المسافة البيضاء المستخدمة في المسافة البادئة):

cat
             dog
             fish

جاء ذلك في ذهني بعد أن تعلمت ما يلي من هذا السؤال :

where T : struct

نحن ، مطوري C # ، جميعنا نعرف أساسيات C #. أعني الإعلانات ، الشروط ، الحلقات ، المشغلين ، إلخ.

البعض منا حتى يتقن أشياء مثل Generics ، وأنواع المجهول ، lambdas ، LINQ ، ...

ولكن ما هي أكثر الميزات أو الحيل المخفية لـ C # حتى المشجعين C # والمدمنين والخبراء بالكاد يعرفون؟

فيما يلي السمات المعلنة حتى الآن:


الكلمات الدالة

سمات

بناء الجملة

  • ?? (coalesce nulls) المشغل من قبل kokos
  • عدد البزات التي كتبها نيك بيراردي
  • where T:new لارس Mæhlum
  • الدنا الضمني بواسطة Keith
  • لامبداس المعلمة من قبل Keith
  • خصائص السيارات بواسطة Keith
  • الاسم المستعار الاسم المستعار بواسطة Keith
  • حرفي سلسلة الحرفية مع @ بواسطة Patrick
  • قيم enum lfoust
  • variablenames by marxidad
  • مشغلي event قبل marxidad
  • تنسيق أقواس سلسلة من Portman
  • معدّل الوصول إلى accessororor بواسطة xanadont
  • عامل شرطي (ثلاثي) ( ?: JasonS بواسطة JasonS
  • مشغلات unchecked وغير unchecked قبل Binoj Antony
  • المشغلين implicit and explicit قبل Flory

سمات اللغة

ميزات Visual Studio

الإطار

الطرق والخصائص

  • أسلوب KiwiBastard String.IsNullOrEmpty() بواسطة KiwiBastard
  • طريقة List.ForEach() بواسطة KiwiBastard
  • BeginInvoke() ، EndInvoke() طرق من قبل Will Dean
  • Nullable<T>.HasValue و Nullable<T>.HasValue Nullable<T>.Value خصائص Nullable<T>.Value بواسطة Rismo
  • طريقة GetValueOrDefault بواسطة John Sheehan

نصائح وخدع

  • طريقة لطيفة لمعاملي الحدث من قبل أندرياس HR Nilsson
  • مقارنات الأحرف الكبيرة بواسطة John
  • الوصول إلى أنواع مجهولة بدون انعكاس بواسطة dp
  • طريقة سريعة لتجديد خصائص جمع بكسل من قبل Will
  • تشبه جافا سكريبت-مثل وظائف مضمنة المجهول من قبل roosteronacid

آخر


أجد أن معظم مطوري C # لا يعرفون أنواع "nullable". أساسا ، الأوليات التي يمكن أن يكون لها قيمة فارغة.

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

اضبط ضعف nullable ، num1 ، إلى null ، ثم اضبط ضعفًا عاديًا ، num2 ، إلى num1 أو -100 إذا كان num1 خاليًا.

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

شيء آخر عن نوع Nullable:

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

يتم إرجاع String.Empty. تحقق من this الرابط لمزيد من التفاصيل


" yield " سيتبادر إلى ذهني. بعض السمات مثل DefaultValueAttribute هي أيضا من بين المفضلة لدي.

الكلمة " var " معروفة أكثر قليلاً ، ولكن يمكنك استخدامها في تطبيقات .NET 2.0 كذلك (طالما أنك تستخدم مترجم NET 3.5 وتعيينه لإخراج رمز 2.0) لا يبدو معروفاً حسنا.

تحرير: kokos ، شكرا لافتا إلى؟ المشغل ، وهذا في الواقع مفيد حقا. نظرًا لأنه من الصعب بعض الشيء بالنسبة لـ google (حيث يتم تجاهلها فقط) ، فإليك صفحة وثائق MSDN الخاصة بهذا المشغل: ?? ??


lambdas ونوع inferrence تم الاستخفاف بها. يمكن أن تحتوي Lambdas على عبارات متعددة وتتضاعف ككائن مفوض متوافق تلقائيًا (فقط تأكد من تطابق التوقيع) كما في:

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

لاحظ أنه ليس لديّ new CancellationEventHandler ولا يجب أن أحدد أنواع sender و e ، حيث يمكن استبعادها من الحدث. وهذا هو السبب في أن هذا أقل تعقيدًا عند كتابة delegate (blah blah) بأكمله delegate (blah blah) والذي يتطلب منك أيضًا تحديد أنواع المعلمات.

لا تحتاج Lambdas إلى إعادة أي شيء ، ونوع الاستدلال قوي للغاية في سياق مثل هذا.

و BTW ، يمكنك دائما العودة Lambdas التي تجعل Lambdas بالمعنى الوظيفي للبرمجة. على سبيل المثال ، هنا lambda الذي يجعل lambda الذي يعالج حدث Button.Click:

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) =>

الآن هذا هو السبب في أنني سعيد لأني اخذت فئة البرمجة الوظيفية :-)

بخلاف المؤشرات في C ، أعتقد أنه الشيء الأساسي الآخر الذي يجب أن تتعلمه :-)


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"

من CLR عبر C # :

عند تطبيع السلاسل ، يوصى بشدة باستخدام ToUpperInvariant بدلاً من ToLowerInvariant لأن Microsoft قامت بتحسين التعليمات البرمجية لإجراء عمليات المقارنة الكبيرة .

أتذكر مرة واحدة أن زميل العمل الخاص بي دائماً غيّر السلاسل إلى الأحرف الكبيرة قبل المقارنة. لقد تساءلت دائمًا لماذا يفعل ذلك لأنني أشعر أنه من "الطبيعي" أن يتم التحويل إلى الأحرف الصغيرة أولاً. بعد قراءة الكتاب الآن أعرف لماذا.


الأدوية البديلة:

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

يسمح لك باستخدام ASimpleName ، بدلاً من Dictionary<string, Dictionary<string, List<string>>> .

استخدمها عندما تستخدم نفس الشيء الكبير الطويل المعقّد في الكثير من الأماكن.


فيما يلي بعض الميزات C # المخفية المثيرة للاهتمام ، في شكل الكلمات الرئيسية C # غير الموثقة:

__makeref

__reftype

__refvalue

__arglist

هذه هي الكلمات الرئيسية C # غير موثقة (حتى يتعرف عليها Visual Studio!) التي تمت إضافتها إلى أكثر فعالية في الملاكمة / إزالة الصندوق قبل الأدوية. وهي تعمل بالتنسيق مع بنية System.TypedReference.

هناك أيضا __ قائمة ، والتي تستخدم لقوائم المعلمات طول متغير.

هناك شيء واحد لا يعرفه System.WeakReference عنه هو System.WeakReference - فئة مفيدة للغاية تقوم بتتبع كائن ما ولكنها تسمح لمجمع البيانات المهملة بجمعها.

ستكون الميزة "المخفية" الأكثر فائدة هي الكلمة الرئيسية لعائد العائد. إنه ليس مخفيًا حقًا ، لكن الكثير من الناس لا يعرفون عنه. بنيت LINQ على قمة هذا ؛ يسمح باستعلامات تأخير التنفيذ عن طريق إنشاء جهاز حالة ضمن الغطاء. نشرت ريموند تشن مؤخرا حول التفاصيل الداخلية ، شجاع .


أعتقد أن أحد أكثر ميزات C # (.NET 3.5) الأقل تقديراً وأقل شهرةً هي " أشجار التعبير" ، خاصة عند دمجها مع Generics و Lambdas. هذا هو نهج لإنشاء API التي تستخدمها المكتبات الأحدث مثل NInject و Moq.

على سبيل المثال ، لنفترض أنني أريد تسجيل طريقة باستخدام واجهة برمجة التطبيقات وأن واجهة برمجة التطبيقات تحتاج إلى الحصول على اسم الأسلوب

نظرا لهذه الفئة:

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

في السابق ، كان من الشائع جدًا رؤية المطورين يقومون بذلك باستخدام السلاسل والأنواع (أو أي شيء آخر يستند إلى حد كبير):

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

حسنا ، هذا يمتص بسبب عدم وجود الكتابة القوية. ماذا لو قمت بإعادة تسمية "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);
    }
}

هذا هو سبب واحد كبير أنني في حالة حب مع Lambdas و Expression Trees في الوقت الحالي.


Not sure why anyone would ever want to use Nullable<bool> though. :-)

True, False, FileNotFound ?


الاتحادات (نوع الذاكرة المشتركة C ++) في C # نقية وآمنة

بدون اللجوء إلى وضع ومؤشرات غير آمنة ، يمكن أن يشارك أعضاء الفئة في مساحة الذاكرة في فئة / بنية. نظرا للفئة التالية:

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

يمكنك تعديل قيم حقول بايت عن طريق معالجة الحقل Int32 والعكس بالعكس. على سبيل المثال ، هذا البرنامج:

    static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

مخرجات هذا:

2147483647
FF FF FF 7F
65535

فقط قم بإضافة باستخدام System.Runtime.InteropServices؛


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;
}

كل شيء آخر ، زائد

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();

الكلمة الأساسية "الافتراضية" في الأنواع العامة:

T t = default(T);

ينتج في "null" إذا كان T هو نوع مرجع ، و 0 إذا كان هو int ، false إذا كان boolean ، إلى آخره.


من ريك ستراهل :

يمكنك سلسلة؟ المشغل بحيث يمكنك القيام حفنة من المقارنات الفارغة.

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

هذا ليس C # في حد ذاته ، لكنني لم أر أي شخص يستخدم System.IO.Path.Combine() حقًا إلى الحد الذي يجب عليه فعله. في الواقع ، تعتبر فئة Path بأكملها مفيدة حقًا ، ولكن لا أحد يستخدمها!

أنا على استعداد للمراهنة على أن كل تطبيق إنتاج يحتوي على الشفرة التالية ، على الرغم من أنه لا ينبغي أن يكون:

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

@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.


خدعي المفضل هو استخدام عامل التشغيل null compelsce والأقواس لإنشاء مجموعات تلقائية لـ لي تلقائياً.

private IList<Foo> _foo;

public IList<Foo> ListOfFoo 
    { get { return _foo ?? (_foo = new List<Foo>()); } }

تجنب التحقق من معالجات الأحداث الفارغة

إضافة مفوض فارغ للأحداث في الإعلان ، قمع الحاجة إلى التحقق من الحدث دائمًا قبل أن يطلق عليه أمر رائع. مثال:

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");
    }
}

يرجى الاطلاع أيضًا على هذه المناقشة ذات الصلة ونشرة هذا المدونة بواسطة Eric Lippert حول هذا الموضوع (والسلبيات المحتملة).


لم أكن أعرف الكلمة الرئيسية "كـ" لفترة طويلة.

MyClass myObject = (MyClass) obj;

ضد

MyClass myObject = obj as MyClass;

سيتم إرجاع القيمة الثانية إذا لم يكن obj MyClass ، بدلاً من طرح استثناء فئة الإرسال.


Environment.NewLine

for system independent newlines.


Mixins. Basically, if you want to add a feature to several classes, but cannot use one base class for all of them, get each class to implement an interface (with no members). Then, write an extension method for the interface , ie

public static DeepCopy(this IPrototype p) { ... }

Of course, some clarity is sacrificed. But it works!


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.


استخدام @ لأسماء المتغيرات التي هي الكلمات الرئيسية.

var @object = new object();
var @string = "";
var @if = IpsoFacto(); 

تاريخ إصدار لغة C #:

هذه هي إصدارات C # المعروفة في وقت كتابة هذه السطور:

ردا على سؤال OP:

ما هي أرقام الإصدارات الصحيحة لـ C #؟ ماذا خرج عندما؟ لماذا لا يمكنني العثور على أي إجابات حول C # 3.5؟

لا يوجد شيء مثل C # 3.5 - سبب الارتباك هنا هو أن C # 3.0 موجود في .NET 3.5. اللغة والإطار يتم إصدارها بشكل مستقل ، ومع ذلك - كما هو CLR ، الذي هو في الإصدار 2.0 ل. NET 2.0 من خلال 3.5 ،. NET 4 إدخال CLR 4.0 ، حزم الخدمات على الرغم من. يحتوي CLR في. NET 4.5 تحسينات مختلفة ، ولكن الإصدار غير واضح: في بعض الأماكن قد يشار إليها باسم CLR 4.5 ( هذه الصفحة MSDN المستخدمة للإشارة إليها بهذه الطريقة ، على سبيل المثال) ، ولكن لا تزال الخاصية Environment.Version تقارير 4.0.xxx.

تتوفر معلومات أكثر تفصيلاً عن العلاقة بين اللغة وإصدارات وقت التشغيل وإطار العمل على C # في موقع Depth . يتضمن ذلك معلومات حول ميزات C # 3.0 التي يمكنك استخدامها عند استهداف .NET 2.0. (إذا كان أي شخص يرغب في جلب كل المحتوى إلى إجابة الويكي هذه ، فإنهم مرحب بهم.)

اعتبارًا من 3 مايو 2017 ، قام فريق C # Language بإنشاء تاريخ إصدارات C # وميزات على repub جيثوب: الميزات المضافة في إصدارات لغة C # . هناك أيضًا صفحة تتعقب ميزات اللغة القادمة والتي تم تنفيذها مؤخرًا .





c# hidden-features