سؤال

بعد المناقشة مع الزملاء فيما يتعلق باستخدام الكلمة الأساسية "var" في C# 3، تساءلت عن آراء الأشخاص حول الاستخدامات المناسبة لاستدلال النوع عبر var؟

على سبيل المثال، استخدمت var بتكاسل في ظروف مشكوك فيها، على سبيل المثال: -

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

الاستخدامات الأكثر شرعية لـ var هي كما يلي: -

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

ومن المثير للاهتمام أن LINQ يبدو وكأنه منطقة رمادية بعض الشيء، على سبيل المثال: -

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

من الواضح ما هي النتائج التي ستكون من حيث أنه سيكون نوعًا ينفذ IEnumerable، ومع ذلك، فهو ليس واضحًا تمامًا بنفس الطريقة التي يعلن بها var عن كائن جديد.

والأمر أسوأ عندما يتعلق الأمر بـ LINQ للكائنات، على سبيل المثال: -

var results = from item in someList
              where item != 3
              select item;

هذا ليس أفضل من المعادل foreach(var item in someList) { // ...} يعادل.

هناك قلق حقيقي بشأن سلامة النوع هنا - على سبيل المثال، إذا أردنا وضع نتائج هذا الاستعلام في طريقة مثقلة تقبل IEnumerable<int> وIEnumerable<double>، فقد يمرر المتصل عن غير قصد النوع الخطأ.

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

هل كانت مفيدة؟

المحلول

ما زلت أعتقد var يمكن أن يجعل التعليمات البرمجية أكثر قابلية للقراءة في بعض الحالات.إذا كان لدي فئة العملاء مع خاصية الطلبات، وأريد تعيين ذلك لمتغير، سأفعل ما يلي:

var orders = cust.Orders;

لا يهمني إذا كان Customer.Orders هو IEnumerable<Order>, ObservableCollection<Order> أو BindingList<Order> - كل ما أريده هو الاحتفاظ بهذه القائمة في الذاكرة لتكرارها أو الحصول على عددها أو شيء من هذا القبيل لاحقًا.

قارن التصريح أعلاه بما يلي:

ObservableCollection<Order> orders = cust.Orders;

بالنسبة لي، اسم النوع هو مجرد ضجيج.وإذا عدت وقررت تغيير نوع العميل.الطلبات أسفل المسار (على سبيل المثال من ObservableCollection<Order> ل IList<Order>) فأنا بحاجة إلى تغيير هذا الإعلان أيضًا - وهو أمر لم أكن لأضطر إلى فعله إذا كنت قد استخدمت var في المقام الأول.

نصائح أخرى

أنا أستعمل var على نطاق واسع.كانت هناك انتقادات بأن هذا يقلل من سهولة قراءة الكود، ولكن لا توجد حجة لدعم هذا الادعاء.

من المسلم به أن هذا قد يعني أنه ليس من الواضح ما هو النوع الذي نتعامل معه.وماذا في ذلك؟هذا هو في الواقع الهدف من التصميم المنفصل.عند التعامل مع الواجهات، فأنت بالتأكيد لا مهتم بنوع المتغير. var يأخذ هذا إلى أبعد من ذلك بكثير، صحيح، لكنني أعتقد أن الحجة تظل كما هي من وجهة نظر سهولة القراءة:لا ينبغي للمبرمج أن يهتم في الواقع بنوع المتغير بل بنوع المتغير يفعل.ولهذا السبب تطلق Microsoft أيضًا على نوع الاستدلال اسم "كتابة البطة".

إذًا، ماذا يفعل المتغير عندما أعلن عنه باستخدام var؟إنه سهل، فهو يفعل كل ما يخبرني به IntelliSense.أي تفكير حول C# يتجاهل IDE لا يرقى إلى الواقع.من الناحية العملية، تتم برمجة كل رمز C# في بيئة تطوير متكاملة (IDE) تدعم IntelliSense.

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

الآن، أصدر فريق C# إرشادات الترميز التي تنص على ذلك var يجب فقط يمكن استخدامها لالتقاط نتيجة عبارة LINQ التي تنشئ نوعًا مجهولاً (لأنه هنا، ليس لدينا بديل حقيقي لـ var).حسنا، المسمار ذلك.طالما أن فريق C# لم يقدم لي حجة سليمة لهذا المبدأ التوجيهي، فسوف أتجاهله لأنه في رأيي المهني والشخصي، فهو مجرد هراء.(آسف؛ليس لدي أي رابط للمبادئ التوجيهية المعنية.)

في الواقع، هناك بعض (سطحيا) تفسيرات جيدة لماذا لا يجب أن تستخدم var لكنني ما زلت أعتقد أنهم مخطئون إلى حد كبير.خذ مثال "قابلية البحث":يدعي المؤلف ذلك var يجعل من الصعب البحث عن الأماكن التي MyType يستخدم.يمين.وكذلك تفعل الواجهات.في الواقع، لماذا أريد أن أعرف أين يتم استخدام الفصل؟قد أكون مهتمًا أكثر بمكان إنشاء مثيل له وسيظل هذا قابلاً للبحث لأنه يجب استدعاء مُنشئه في مكان ما (حتى لو تم ذلك بشكل غير مباشر، يجب ذكر اسم النوع في مكان ما).

Var، في رأيي، في C# هو شيء جيدtm.أي متغير تمت كتابته على هذا النحو لا يزال مكتوبًا بقوة، ولكنه يحصل على نوعه من الجانب الأيمن من المهمة حيث تم تعريفه.نظرًا لأن معلومات النوع متاحة على الجانب الأيمن، ففي معظم الحالات، يكون من غير الضروري والمطول للغاية إدخالها على الجانب الأيسر أيضًا.أعتقد أن هذا يزيد بشكل كبير من سهولة القراءة دون تقليل أمان الكتابة.

من وجهة نظري، يعد استخدام اصطلاحات التسمية الجيدة للمتغيرات والأساليب أكثر أهمية من منظور سهولة القراءة من معلومات النوع الصريحة.إذا كنت بحاجة إلى معلومات النوع، فيمكنني دائمًا المرور فوق المتغير (في VS) والحصول عليه.بشكل عام، على الرغم من ذلك، لا ينبغي أن تكون معلومات النوع الصريحة ضرورية للقارئ.بالنسبة للمطور، في VS لا يزال بإمكانك الحصول على Intellisense، بغض النظر عن كيفية الإعلان عن المتغير.بعد أن قلت كل ذلك، ربما لا تزال هناك حالات يكون فيها من المنطقي الإعلان عن النوع صراحةً - ربما لديك طريقة تُرجع قيمة List<T>, ، لكنك تريد التعامل معها على أنها IEnumerable<T> في طريقتك.للتأكد من أنك تستخدم الواجهة، فإن الإعلان عن متغير نوع الواجهة يمكن أن يوضح ذلك.أو ربما تريد الإعلان عن متغير بدون قيمة أولية - لأنه يحصل على قيمة على الفور بناءً على شرط ما.في هذه الحالة تحتاج إلى النوع.إذا كانت معلومات النوع مفيدة أو ضرورية، فاستمر في استخدامها.ومع ذلك، أشعر أن هذا ليس ضروريًا عادةً وأن قراءة الكود أسهل بدونه في معظم الحالات.

لا شيء من هذا صحيح تماما. var يمكن أن يكون لها آثار إيجابية وسلبية على سهولة القراءة.في رأيي، var يجب استخدامه عندما يكون أي مما يلي صحيحًا:

  1. النوع مجهول (حسنًا، ليس لديك أي خيار هنا، كما هو الحال يجب يكون فار في هذه الحالة)
  2. النوع واضح بناءً على التعبير المخصص (أي: var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

var ليس له أي تأثير على الأداء، فهو سكر نحوي؛يستنتج المترجم النوع ويحدده بمجرد تجميعه في IL؛لا يوجد شيء في الحقيقة ديناميكية حول هذا الموضوع.

من إريك ليبرت، أحد كبار مهندسي تصميم البرمجيات في فريق C#:

لماذا كان var الكلمة الرئيسية المقدمة؟

هناك سببان ، أحدهما موجود اليوم ، والذي سيظهر في 3.0.

السبب الأول هو أن هذا الرمز قبيح بشكل لا يصدق بسبب كل التكرار:

Dictionary<string, List<int>> mylists = new Dictionary<string, List<int>>();

وهذا مثال بسيط - لقد كتبت أسوأ.في أي وقت تضطر إلى كتابة نفس الشيء مرتين تمامًا ، وهذا هو التكرار الذي يمكننا إزالته.أجمل بكثير في الكتابة

var mylists = new Dictionary<string,List<int>>();

ودع المترجم يكتشف ما يعتمد النوع على المهمة.

ثانياً ، يقدم C# 3.0 أنواعًا مجهولة.نظرًا لأن الأنواع المجهولة بالتعريف ليس لها أسماء ، فأنت أنت يحتاج لتكون قادرة على استنتاج نوع المتغير من التعبير التهيئة إذا كان نوعه مجهول الهوية.

التأكيد على الألغام.المقال كله، لا يزال الإصدار C# 3.0 مكتوبًا بشكل ثابت وصادق!, ، وما تلاها مسلسل جيدة جدًا.

هذا هو ما var هو ل.ربما لن تعمل الاستخدامات الأخرى بشكل جيد.أي مقارنة مع JScript أو VBScript أو الكتابة الديناميكية هي عبارة عن كلام فارغ تمامًا.لاحظ مرة أخرى، var يكون مطلوب لكي تعمل بعض الميزات الأخرى في .NET.

أعتقد أن استخدام var يجب أن يقترن بأسماء المتغيرات المختارة بحكمة.

ليس لدي مشكلة في استخدام var في عبارة foreach، بشرط ألا يكون الأمر على النحو التالي:

foreach (var c in list) { ... }

لو كان الأمر أكثر مثل هذا:

foreach (var customer in list) { ... }

...فمن المرجح أن يفهم شخص يقرأ الكود ما هي "القائمة".إذا كان لديك القدرة على التحكم في اسم متغير القائمة نفسه، فهذا أفضل.

ويمكن أن ينطبق الشيء نفسه على المواقف الأخرى.هذا عديم الفائدة إلى حد ما:

var x = SaveFoo(foo);

...لكن هذا منطقي:

var saveSucceeded = SaveFoo(foo);

أعتقد أن كل واحد بمفرده.لقد وجدت نفسي أفعل هذا، وهو أمر جنوني:

var f = (float)3;

أحتاج إلى نوع من برنامج var المكون من 12 خطوة.اسمي مات، وأنا (ab) أستخدم var.

لقد اعتمدنا مبدأ "القواعد للأشخاص، وليس للآلات"، استنادًا إلى افتراض أنك تقضي وقتًا أطول في وضع الصيانة عدة مرات مقارنة بالتطوير الجديد.

بالنسبة لي، هذا يستبعد الحجة القائلة بأن المترجم "يعرف" نوع المتغير - بالتأكيد، لا يمكنك كتابة كود غير صالح في المرة الأولى لأن المترجم يوقف تجميع الكود الخاص بك، ولكن عندما يقرأ المطور التالي الكود وفي غضون 6 أشهر، يجب أن يكونوا قادرين على استنتاج ما يفعله المتغير بشكل صحيح أو غير صحيح وتحديد سبب المشكلات بسرعة.

هكذا،

var something = SomeMethod();

محظور بموجب معايير الترميز لدينا، ولكن يتم تشجيع ما يلي في فريقنا لأنه يزيد من سهولة القراءة:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}

إنه ليس سيئًا، إنه شيء أسلوبي يميل إلى أن يكون ذاتيًا.يمكن أن يضيف تناقضات، عندما تستخدم var وعندما لا تستخدمه.

حالة أخرى مثيرة للقلق، في المكالمة التالية، لا يمكنك معرفة النوع الذي تم إرجاعه بمجرد النظر إلى الكود CallMe:

var variable = CallMe();

هذه هي شكواي الرئيسية ضد var.

أستخدم var عندما أعلن عن مندوبين مجهولين في الأساليب، يبدو var بطريقة ما أنظف مما لو كنت سأستخدمه Func.خذ بعين الاعتبار هذا الرمز:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

يحرر:تم تحديث نموذج التعليمات البرمجية الأخير بناءً على إدخال جوليان

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

هل استخدام Intellisense كسول؟إنها كتابة أقل من الاسم بالكامل.أم أن هناك أشياء أقل عملا ولكنها لا تستحق النقد؟أعتقد أن هناك، وvar هو واحد منهم.

الوقت الأكثر احتمالاً الذي ستحتاج فيه إلى ذلك هو للأنواع المجهولة (حيث يكون مطلوبًا بنسبة 100٪)؛ولكنه أيضًا يتجنب التكرار في الحالات التافهة، ويجعل IMO الخط أكثر وضوحًا.لست بحاجة لرؤية النوع مرتين لإجراء تهيئة بسيطة.

على سبيل المثال:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(من فضلك لا تقم بتحرير hscroll في ما سبق - فهو يثبت هذه النقطة نوعًا ما !!!)

ضد:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

ومع ذلك، هناك حالات يكون فيها ذلك مضللاً، ويمكن أن يسبب أخطاء.كن حذرا باستخدام var إذا لم يكن المتغير الأصلي والنوع الذي تمت تهيئته متطابقين.على سبيل المثال:

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}

// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);

حالة واحدة محددة حيث يكون var صعبًا:مراجعات التعليمات البرمجية دون اتصال بالإنترنت، خاصة تلك التي تتم على الورق.

لا يمكنك الاعتماد على تمرير الماوس لذلك.

لا أرى ما هو الأمر الكبير..

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

لا يزال لديك ذكاء كامل بشأن "شيء ما"، وفي حالة أي حالة غامضة، يكون لديك اختبارات الوحدة الخاصة بك، أليس كذلك؟( هل أنت؟)

إنها ليست varchar، وليست خافتة، وهي بالتأكيد ليست كتابة ديناميكية أو ضعيفة.يتم إيقاف الجنون مثل هذا:

List<somethinglongtypename> v = new List<somethinglongtypename>();

وتقليل هذا الفوضى الذهنية الكاملة إلى:

var v = new List<somethinglongtypename>();

لطيفة، ليست لطيفة تمامًا مثل:

v = List<somethinglongtypename>();

ولكن بعد ذلك هذا ما بوو هو ل.

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

أسباب وجيهة لاستخدام var الكلمات الرئيسية هي على سبيل المثال:

  • حيث تكون هناك حاجة إليها، أي.للإعلان عن مرجع لنوع مجهول.
  • حيث يجعل الكود أكثر قابلية للقراءة، أي.إزالة الإعلانات المتكررة.

غالبًا ما تؤدي كتابة نوع البيانات إلى تسهيل متابعة التعليمات البرمجية.فهو يعرض أنواع البيانات التي تستخدمها، بحيث لا تضطر إلى معرفة نوع البيانات من خلال معرفة ما يفعله الكود أولاً.

نظرًا لمدى قوة Intellisense الآن، لست متأكدًا من أن قراءة var أصعب من وجود متغيرات الأعضاء في الفصل، أو المتغيرات المحلية في طريقة يتم تحديدها خارج منطقة الشاشة المرئية.

إذا كان لديك سطر من التعليمات البرمجية مثل

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

هل القراءة أسهل أو أصعب بكثير من:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

أعتقد أن الشيء الأساسي في تقنية VAR هو استخدامها فقط عندما يكون ذلك مناسبًا، على سبيل المثال.عند القيام بأشياء في Linq يسهل ذلك (وربما في حالات أخرى).

اذا كنت تملك يملك نوع لشيء ما، ثم يجب عليك استخدامه - عدم القيام بذلك هو كسل بسيط (على عكس الكسل الإبداعي الذي يتم تشجيعه بشكل عام - غالبًا ما يعمل المبرمجون الجيدون بجد ليكونوا كسالى ويمكن اعتبارهم مصدر الشيء) في المقام الأول).

يعد الحظر الشامل أمرًا سيئًا مثل إساءة استخدام البنية في المقام الأول، ولكن يجب أن يكون هناك معيار ترميز معقول.

الشيء الآخر الذي يجب تذكره هو أنه ليس من نوع VB لأنه لا يمكنه تغيير الأنواع - فهو يكون متغير مكتوب بقوة، إنه مجرد استنتاج من النوع (وهذا هو السبب في وجود أشخاص سيجادلون بأنه ليس من غير المعقول استخدامه في، على سبيل المثال، foreach ولكني لا أوافق على ذلك لأسباب تتعلق بسهولة القراءة وقابلية الصيانة).

أظن أن هذا الشخص سوف يركض ويهرب (-:

مورف

بالتأكيد، int من السهل، ولكن عندما يكون نوع المتغير IEnumerable<MyStupidLongNamedGenericClass<int, string>>, ، var يجعل الأمور أسهل بكثير.

مسروقة من قم بالنشر حول هذه المشكلة في CodingHorror:


لسوء الحظ، لقد أخطأت أنت والجميع في الأمر إلى حد كبير.على الرغم من أنني أتفق معك على أن التكرار ليس بالأمر الجيد، إلا أن الطريقة الأفضل لحل هذه المشكلة هي القيام بشيء مثل ما يلي:

MyObject m = new();

أو إذا كنت تقوم بتمرير المعلمات:

الشخص ع = جديد ("الاسم الأول"، "اسم العائلة)؛"

حيث عند إنشاء كائن جديد، يستنتج المترجم النوع من الجانب الأيسر، وليس الأيمن.يتمتع هذا بمزايا أخرى مقارنة بـ "var"، حيث يمكن استخدامه في الإعلانات الميدانية أيضًا (هناك أيضًا بعض المجالات الأخرى التي يمكن أن تكون مفيدة أيضًا، لكنني لن أتطرق إليها هنا).

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

نيكولاس بالدينو .NET/C# MVP في 20 يونيو 2008 الساعة 08:00 صباحًا


أعتقد أنه إذا كان همك الرئيسي هو الكتابة بشكل أقل - فلن تكون هناك أي حجة ستمنعك من استخدامه.

إذا كنت ستفعل ذلك فقط أبدًا كن الشخص الذي ينظر إلى الكود الخاص بك، فمن يهتم؟وإلا ففي مثل هذه الحالة:

var people = Managers.People

لا بأس، ولكن في مثل هذه الحالة:

var fc = Factory.Run();

إنها دائرة كهربائية قصيرة، أي استنتاجات فورية يمكن أن يبدأ عقلي في تكوينها من "اللغة الإنجليزية" للشفرة.

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

استخدام var بدلاً من الكتابة الصريحة تجعل إعادة البناء أسهل بكثير (لذلك يجب أن أتناقض مع الملصقات السابقة التي كانت تعني أنها لا تحدث فرقًا أو أنها كانت "سكرًا نحويًا" بحتًا).

يمكنك تغيير نوع الإرجاع لطرقك دون تغيير كل ملف يتم استدعاء هذه الطريقة فيه.يتصور

...
List<MyClass> SomeMethod() { ... }
...

الذي يستخدم مثل

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

إذا كنت تريد إعادة البناء SomeMethod() لإرجاع ا IEnumerable<MySecondClass>, ، فسيتعين عليك تغيير تعريف المتغير (أيضًا داخل ملف foreach) في كل مكان استخدمت فيه الطريقة.

إذا كتبت

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

بدلاً من ذلك، ليس عليك تغييره.

@أكو:أحد الأمثلة على ذلك هو مراجعات الكود.مثال آخر هو سيناريوهات إعادة البناء.

في الأساس، لا أرغب في البحث عن الكتابة باستخدام الماوس.قد لا يكون متاحا.

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

سي# var رائع جدًا في ذلك تبدو مثل الكتابة الديناميكية، ولكن في الواقع ثابتة الكتابة - يفرض المترجم الاستخدام الصحيح.

إن نوع المتغير الخاص بك ليس مهمًا حقًا (لقد قيل هذا من قبل).يجب أن يكون واضحًا نسبيًا من السياق (تفاعلاته مع المتغيرات والأساليب الأخرى) واسمه - لا تتوقعه قائمة العملاء لاحتوائه على int...

ما زلت أنتظر رؤية رأي مديري في هذا الأمر - لقد حصلت على موافقة شاملة لاستخدام أي تصميمات جديدة في الإصدار 3.5، ولكن ماذا سنفعل بشأن الصيانة؟

في مقارنتك بين IEnumerable<int> و IEnumerable<double> لا داعي للقلق - إذا قمت بتمرير نوع خاطئ، فلن يتم تجميع التعليمات البرمجية الخاصة بك على أي حال.

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

Var هناك حاجة ماسة لـ Linq:

var anonEnumeration =
    from post in AllPosts()
    where post.Date > oldDate
    let author = GetAuthor( post.AuthorId )
    select new { 
        PostName = post.Name, 
        post.Date, 
        AuthorName = author.Name
    };

انظر الآن anonEnumeration في التحسس وسيظهر شيء من هذا القبيل IEnumerable<'a>

foreach( var item in anonEnumeration ) 
{
    //VS knows the type
    item.PostName; //you'll get intellisense here

    //you still have type safety
    item.ItemId;   //will throw a compiler exception
}

يعد برنامج التحويل البرمجي C# ذكيًا جدًا - فالأنواع المجهولة التي يتم إنشاؤها بشكل منفصل سيكون لها نفس النوع الذي تم إنشاؤه إذا كانت خصائصها متطابقة.

خارج ذلك، طالما أن لديك الذكاء فمن المنطقي استخدامه var في أي مكان يكون السياق واضحا.

//less typing, this is good
var myList = new List<UnreasonablyLongClassName>();

//also good - I can't be mistaken on type
var anotherList = GetAllOfSomeItem();

//but not here - probably best to leave single value types declared
var decimalNum = 123.456m;

أعتقد أن ذلك يعتمد على وجهة نظرك.أنا شخصياً لم أواجه أي صعوبة في فهم جزء من التعليمات البرمجية بسبب ذلك var "سوء الاستخدام"، وأنا وزملائي في العمل نستخدمه كثيرًا في كل مكان.(أوافق على أن Intellisense يعد بمثابة مساعدة كبيرة في هذا الصدد.) وأنا أرحب به كوسيلة لإزالة الأخطاء المتكررة.

بعد كل شيء، إذا كانت البيانات مثل

var index = 5; // this is supposed to be bad

var firstEligibleObject = FetchSomething(); // oh no what type is it
                                            // i am going to die if i don't know

إذا كان من المستحيل حقًا التعامل معها، فلن يستخدم أحد اللغات المكتوبة ديناميكيًا.

أنا أستخدم var فقط عندما يكون من الواضح معرفة النوع المستخدم.

على سبيل المثال، سأستخدم var في هذه الحالة، لأنك تستطيع أن ترى على الفور أن x سيكون من النوع "MyClass":

var x = new MyClass();

لن أستخدم var في مثل هذه الحالات، لأنه يتعين عليك سحب الماوس فوق الكود وإلقاء نظرة على تلميح الأداة لمعرفة نوع MyFunction الذي يُرجعه:

var x = MyClass.MyFunction();

خصوصا أنا أبداً استخدم var في الحالات التي لا يكون فيها الجانب الأيمن طريقة، بل قيمة فقط:

var x = 5;

(لأن المترجم لا يمكنه معرفة ما إذا كنت أريد بايتًا أو قصيرًا أو int أو أيًا كان)

بالنسبة لي، الكراهية تجاه var يوضح سبب أهمية ثنائية اللغة في .NET.بالنسبة لمبرمجي C# الذين قاموا أيضًا باستخدام VB .NET، فإن مزايا var واضحة بشكل حدسي.إعلان C# القياسي لـ:

List<string> whatever = new List<string>();

هو ما يعادل، في VB .NET، كتابة هذا:

Dim whatever As List(Of String) = New List(Of String)

لا أحد يفعل ذلك في VB .NET، بالرغم من ذلك.سيكون الأمر سخيفًا، لأنه منذ الإصدار الأول من .NET، تمكنت من القيام بذلك...

Dim whatever As New List(Of String)

... الذي يقوم بإنشاء المتغير وتهيئته جميعًا في سطر واحد مضغوط بشكل معقول.آه، ولكن ماذا لو كنت تريد IList<string>, ، وليس أ List<string>؟حسنًا، في VB .NET هذا يعني أنه عليك القيام بذلك:

Dim whatever As IList(Of String) = New List(Of String)

تمامًا كما يجب عليك فعله في لغة C#، ومن الواضح أنك لا تستطيع استخدامه var ل:

IList<string> whatever = new List<string>();

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

استخدمه للأنواع المجهولة - وهذا هو الغرض منه.أي شيء آخر هو استخدام بعيد جدا.مثل العديد من الأشخاص الذين نشأوا على لغة C، اعتدت أن أنظر إلى يسار الإعلان عن النوع.أنا لا أنظر إلى الجانب الأيمن إلا إذا اضطررت لذلك.استخدام var لأن أي تصريح قديم يجعلني أفعل ذلك طوال الوقت، وهو ما أجده شخصيًا غير مريح.

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

تعد المعايير أمرًا جيدًا على وجه التحديد لأنها تعني أنه من المرجح أن تكون قادرًا على التقاط كود عشوائي وتكون قادرًا على الحصول عليه بسرعة.كلما زادت الأشياء المختلفة، أصبح الأمر أصعب.والانتقال إلى نمط "var everywhere" يجعل كبير اختلاف.

لا أمانع في الكتابة الديناميكية، ولا أمانع في الكتابة الضمنية - باللغات المصممة لهم.أنا أحب بايثون تماما.لكن لغة #C تم تصميمها كلغة مكتوبة بشكل ثابت وهذا هو ما يجب أن تبقى عليه.كان كسر قواعد الأنواع المجهولة أمرًا سيئًا بما فيه الكفاية؛إن السماح للناس بأخذ ذلك إلى أبعد من ذلك وكسر مصطلحات اللغة بشكل أكبر هو أمر لست سعيدًا به.والآن بعد أن خرج الجني من القمقم، فلن يعود إليه مرة أخرى.سيتم تقسيم لغة C# إلى معسكرات.ليس جيدا.

في كثير من الأحيان أثناء الاختبار، أجد نفسي أمتلك كودًا مثل هذا:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

الآن، في بعض الأحيان، أريد أن أرى ما يحتويه SomeOtherThing نفسه، SomeOtherThing ليس هو نفس النوع الذي ترجعه CallMethod().نظرًا لأنني أستخدم var، فقد قمت فقط بتغيير هذا:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

الى هذا:

var something = myObject.SomeProperty.SomeOtherThing;

بدون var، سأضطر إلى الاستمرار في تغيير النوع المعلن على الجانب الأيسر أيضًا.أعلم أنها بسيطة، لكنها مريحة للغاية.

للعشاق الذين يفكرون var يوفر الوقت، حيث يتطلب الأمر ضغطات أقل على المفاتيح للكتابة:

StringBuilder sb = new StringBuilder();

من

var sb = new StringBuilder();

احسبهم إذا كنت لا تصدقني ...

19 مقابل 21

سأشرح لك إذا اضطررت لذلك، لكن فقط حاول...(اعتمادًا على الحالة الحالية لحساسيتك الذكية، قد تضطر إلى كتابة زوجين إضافيين لكل منهما)

وهذا صحيح لكل نوع يمكن أن يخطر ببالك !!

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

لقد قمت بتقسيم var في جميع الأماكن، والأماكن الوحيدة المشكوك فيها بالنسبة لي هي الأنواع القصيرة الداخلية، على سبيل المثال.أنا أفضل int i = 3; زيادة var i = 3;

من المؤكد أنه يمكن أن يجعل الأمور أسهل، من الكود الذي كتبته بالأمس:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

سيكون هذا مطولًا للغاية بدونه var.

إضافة:قضاء القليل من الوقت مع اللغة حقيقي نوع الاستدلال (على سبيل المثالF#) سيُظهر مدى جودة المترجمين في الحصول على نوع التعبيرات بشكل صحيح.وهذا يعني بالتأكيد أنني أميل إلى الاستخدام var بقدر ما أستطيع، واستخدام نوع صريح يشير الآن إلى أن المتغير ليس من نوع تعبير التهيئة.

لا شيء، باستثناء أنه ليس من الضروري كتابة اسم النوع مرتين. http://msdn.microsoft.com/en-us/library/bb383973.aspx

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top