2

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
}

行を使用しようとすると、 IntelliSenseとコンパイラの両方がオブジェクト型であると通知します。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を使用しています。

編集:正しいコードが添付されました。

4

8 に答える 8

10

私は問題を見ていると思います。DataRowCollection は非ジェネリックであるため、コンパイラが認識しているのは、Object 型のオブジェクトが含まれていることだけです。それが一般的なデータ構造であった場合、これはうまくいったでしょう。

于 2008-12-30T16:57:31.227 に答える
3

これ:

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

Visual Studio 2008 で、Bleh と Blah の両方を表示するインテリセンスが得られます。

そのようなことはありましたか、それともまさにそれでしたか?あなたが示したコード以外にも、インテリセンスをつまずかせるものがあるかもしれません。

実際の質問に答えるために。タイプをスペルアウトする場合と を使用する場合の唯一の違いは、var場合によっては、正しいタイプがない場合に var を使用する必要があることです。私が間違っていなければ、これは匿名型を使用している場合にのみ関係します。

他に違いはなく、コンパイラは右側と同じ型を左側に選択します。

編集: 1つの違いを指摘してくれた@Telosに感謝します var を使用する場合、もちろん、宣言時に変数に値を指定する必要があります。これは、右側の式のタイプを使用して左辺の変数。タイプをスペルアウトするとき、もちろん、値を指定しないことを選択できます。

于 2008-12-24T14:06:42.950 に答える
2

私の推測では、somethingThatReturnsY実際には X を返すと宣言されていますが、実際には Y を返す場合でもそうです。yasを宣言するY y = somethingThatReturnsY();と、コンパイルに失敗することが予想されます。

のルールvarは非常に単純です (それが機能する場合には、実行を停止するためのさまざまな制限がありますvar x = null;

var本当に間違ったことをしていると思われる場合は、デモ用に短いが完全なプログラムを投稿してください。

于 2008-12-24T14:20:33.467 に答える
1

コンソール アプリケーションで次のコードを使用して、これを再現しようとしました。

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() { }
}

これは期待どおりに機能し、IntelliSense は正しく、Reflectorはそれjが typeであることを示していyます。私の推測では、あなたが怪しい何かを経験している場合、ここでの単純なケースよりも複雑であると思います.

Visual Studio 2008 RTM も使用しています。

于 2008-12-24T14:10:14.690 に答える
1

DataTable.Rows は、InternalDataCollectionBase を実装する DataRowCollection を返し、次に ICollection と IEnumerable を実装します。コード

foreach(DataRow row in dt.Rows) { }

DataRowCollection 内の各項目を DataRow にキャストします。これを次のように変更することで実証できます。

foreach(int row in dt.Rows) { }

これはコンパイルされますが、InvalidCastException をスローします。

DataRowCollection が実装されている場合IEnumerable<DataRow>、それはコンパイルされず、var を使用すると、リスト内の各オブジェクトが DataRow として型指定されます。

于 2010-01-27T18:52:30.497 に答える
0

正常に動作します。コンパイラが正しいデータ型を判断できない場合、オブジェクト型を「オブジェクト」として配置します。

于 2008-12-30T17:08:29.847 に答える
0

サンプル コードで十分な情報が提供されているとは思えません。あなたが説明した動作をエミュレートしようとする小さなプログラムを作成しました:

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 が X ではなく Y タイプを解決していることを明確に示しています。

関数が X 参照としてではなく、Y 参照として Y を返すことは確かですか?

于 2008-12-24T14:20:55.277 に答える