質問
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を使用しています。
編集:正しいコードが添付
。解決
私は問題を参照してくださいと思います。 DataRowCollectionは非ジェネリックであるため、コンパイラが知っている唯一のものは、それはObject型のオブジェクトが含まれています。それは、一般的なデータ構造であったならば、これは働いていると思います。
他のヒント
この:
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と何とか両方を示す私を与えます。
は、のようなもののこと、またはの正確のものを持っていましたか?あなたが示したコードよりもインテリセンスをつまずか他のものがあるかもしれません。
実際の質問に答えるために。タイプを綴り、およびvar
を使用しての唯一の違いは、いくつかのケースでは、<全角>ということである必要がありますの利用VAR、あなたは、単にそれのための正しい型を持っていないとき。あなたは匿名型を使用しているとき、これは、私が間違っていない場合は、のみ関係します。
は、他の違いはありません、それが右側にありとしてコンパイラは、左側に同じタイプを選択します。
編集:1点の差が使用している場合ということであることを指摘して @Telos のおかげ右辺の式の型が左辺の変数の型を決定するために使用されているので、varが、あなたはもちろん、変数に宣言時に値を与える必要があります。タイプを綴るとき、あなたはもちろんoptの値を与えないようにすることができます。
私の推測では、その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() { }
}
予想通りこれは、IntelliSenseは、正しく動作し、反射にはj
がであることを示していますy
を入力します。私の推測では、あなたが怪しい何かを経験している場合、それはここでは、単純な場合より複雑であるということです。
私ものVisual Studio 2008のRTMを使用しています。
DataTable.Rowsは、順番にいるICollectionとのIEnumerableを実装InternalDataCollectionBaseを実装DataRowCollectionを返します。コード
foreach(DataRow row in dt.Rows) { }
は、のDataRowにDataRowCollection内の各アイテムをキャスト。あなたはそれを変更することでこれを実証することができます。
foreach(int row in dt.Rows) { }
コンパイルしますが、InvalidCastExceptionがスローされます。
DataRowCollectionはIEnumerable<DataRow>
を実装した場合、それはの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を解決していることを示しています。
あなたの関数がY基準としてではなく、X基準としてYを返すことを確認していますか?
これは、それが必要として動作します。コンパイラは、正しいデータ型を決定することができない場合には、「オブジェクト」としてオブジェクト型を置く。
、DateRowCollectionはIEnumerableインターフェイスかかわらアクセスされます。 DataRowにアクセスするために使用される具体的な方法は、現在と呼ばれるオブジェクトを返します。だから、varキーワードは、型を推論するために、現在のメソッドの戻り値を見ている。