في C # متى تكون الكلمة الأساسية فارغة من كتابة ذلك؟

StackOverflow https://stackoverflow.com/questions/391462

  •  23-08-2019
  •  | 
  •  

سؤال

قدم C # 3.0 var الكلمة الرئيسية. وعندما تم تجميعها، سيقوم المحول البرمجي بإدخال الأنواع المناسبة لك. هذا يعني أنه سيعمل حتى على وقت تشغيل 2.0. حتى الان جيدة جدا. ولكن في اليوم الآخر وجدت حالة حيث، var سيتم استبدال الكلمة الأساسية كائن فقط وبالتالي غير محدد بما فيه الكفاية. قل لديك شيء مثل:

var data = AdoMD.GetData(...); // GetData returns a DataTable

foreach (var row in data.Rows)
{
     string blah = (string)row[0]; // it fails since it's of type object
}

عندما أحاول استخدام الصف كليهما intressisense. ويخبرني المحول البرمجي أنه من نوع الكائن. data.Rows هو من النوع System.Data.DataRowCollection. وبعد الأعمال التالية:

var data = AdoMD.GetData(...); // GetData returns a DataTable

foreach (DataRow row in data.Rows)
{
     string blah = (string)row[0]; // works since it now has the right type
}

هذا ليس سؤالا حول استخدام Var، هناك مؤشر ترابط لذلك هنا.

أنا أستخدم Visual Studio 2008 SP1 BTW.

تحرير: رمز الصحيح المرفقة الآن.

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

المحلول

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

نصائح أخرى

هذه:

using System;

namespace Test
{
    public class X
    {
        public String Bleh;
    }

    public class Y : X
    {
        public String Blah;
    }

    public static class Program
    {
        public static void Main()
        {
            var y = SomeFunctionThatReturnsY();
            // y. <-- this gives me both Blah and Bleh in the dropdown
        }

        public static Y SomeFunctionThatReturnsY()
        {
            return new Y();
        }
    }
}

يعمل كما هو متوقع، فإنه يعطيني Intellisense عرض كل من Bleh و Blah، في Visual Studio 2008.

هل لديك شيء مثل ذلك، أو بالضبط الذي - التي؟ قد يكون هناك أشياء أخرى تقوم بها Trip Up Intressisense من الرمز الذي أظهرته.

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

لا يوجد اختلاف آخر، وسيقوم المحول البرمجي باختيار نفس النوع على الجانب الأيسر أثناء وجوده على الجانب الأيمن.

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

تخميني هو ذلك somethingThatReturnsY في الواقع أعلن للعودة X - حتى لو ترجع Y في الممارسة العملية. أتوقع أنه إذا كنت تعلن y كما Y y = somethingThatReturnsY(); سوف تفشل في الترجمة.

القواعد ل var بسيطة جدا (للحالات التي يعمل فيها - هناك قيود مختلفة لإيقافك var x = null; إلخ.

إذا كنت تعتقد var حقا يفعل الشيء الخطأ، يرجى نشر برنامج قصير ولكن كامل لإظهار.

حاولت إعادة إنتاج هذا مع التعليمات البرمجية التالية في تطبيق وحدة التحكم.

class Program
{
    static void Main(string[] args)
    {
        var j = returny();
        j.blah();
    }

    private static y returny()
    {
        return new y();
    }
}

class x
{
}

class y : x
{
    public void blah() { }
}

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

أنا أستخدم Visual Studio 2008 RTM كذلك.

DataTable.Rows إرجاع DatarowCollection الذي ينفذ InternalDActAllectionBase، والتي بدورها تنفذ iCollection و ienumerable. الرمز

foreach(DataRow row in dt.Rows) { }

يلقي كل عنصر في datarowcollection إلى datarow. يمكنك إظهار ذلك عن طريق تغييره إلى

foreach(int row in dt.Rows) { }

التي تجمع ولكن يلقي invalidcastException.

إذا تم تنفيذ DatarowCollection IEnumerable<DataRow> ثم لن تجميع واستخدام VAR من شأنه كتابة كل كائن في القائمة كمسارو.

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

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var y = SomeFunctionThatReturnsY();

        MessageBox.Show(y.bla);

        return;
    }

    private Y SomeFunctionThatReturnsY()
    {
        return new Y();
    }
}

internal class X { }

internal class Y : X
{
    public string bla = "Saw a Y, not an X";
}

لكن الإخراج يوضح بوضوح أن VAR يحل نوع Y، وليس X.

هل أنت متأكد من أن دئتك ترجع ذ بي كمرجع ذ، وليس كمرجع X؟

وهي تعمل كما يجب. يضع نوع الكائن ك "كائن" عندما يكون التحويل البرمجي غير قادر على تحديد نوع البيانات الصحيح.

عند استخدام الكلمة الأساسية foreach، يتم الوصول إلى CaterowCollection على الرغم من واجهة iEnumerable. تسمى الأسلوب المحدد المستخدم للوصول إلى Datarow الحالية وإرجاع كائن. لذلك تنظر الكلمة الرئيسية في Var إلى قيمة الإرجاع للطريقة الحالية لاستنتاج النوع.

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