4

リンクのように:http://msdn.microsoft.com/en-us/library/bb383973.aspx

...暗黙的に型指定されたローカル変数は、自分で型を宣言したかのように厳密に型指定されますが、型はコンパイラによって決定されます...

しかし、私はそのようなコードを持っています:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["user"] == null) Response.Redirect("Default.aspx");

        StringBuilder sb = new StringBuilder();

        foreach (var item in Session)
        {
            sb.Append("Session Parameter: [");
            sb.Append(item);
            sb.Append("]<p />Guid Value: [");
            sb.Append(Session[item] + "]");
        }

        Response.Write(sb.ToString());
    }

Visual Studio で次のようなエラーが発生します。

引数 1: 行の 'object' から 'string' に変換できません:

 sb.Append(Session[item] + "]");

しかし、デバッガーで見たように、item実行時に型として識別しています。string

msdn/in 本で読んだとき、それは RTTI とは関係ないvarと思いました。コンパイラは、コンパイル時に etc のvarように明示的に型を指定して変数を変更するだけです。string, int

なぜそのようなエラーをキャッチしたのですか?

4

7 に答える 7

8

C# でのvar宣言は厳密に型指定されていますが、この場合、 value で非ジェネリック コレクション型を扱っていますSession。これにより、C#objectは の型を選択するため、.を必要とする位置でitem使用しようとすると、後でエラーが発生します。itemstring

非ジェネリック コレクションの場合は、foreachブロックにイテレータ変数を明示的に入力する必要があります

foreach(string item in Session) { 
  ...
}
于 2013-03-09T02:00:03.207 に答える
3

「なぜそのようなエラーをキャッチしたのですか?」-sb.Append(Session[item] + "]");は文字列を期待しているため - を文字列にキャストする必要がありSession[item]ます:

sb.Append(((string)Session[item]) + "]");

MSDN の記事How to: Read Values from Session State に従ってください。

于 2013-03-09T02:00:08.157 に答える
2

この場合、SessionHttpSessionStateの実装IEnumerableです (実装された場合も同じことが起こりIEnumerable<object>ます) ためvar、コンパイラによって次のようにマップされます。

  foreach (object item in Session)
  {

この場合、これは である可能性が高いIEnumerableため、 でタイプを明示的に指定する必要がありますforeach

  foreach (string item in Session)
  {

foreachこれは、非ジェネリックIEnumerableコレクションで許可されます。

あなたの主な質問については:

C# var には強い型がありますか?

はい。この場合、コレクション自体は厳密な型を提供しないため、 をvar使用しSystem.Objectます。

于 2013-03-09T01:59:55.310 に答える
1

オブジェクトが異なるタイプであるためです。派生クラスがその基本クラスと異なる理由とほぼ同じです (例: class D : B{})。すべてのクラス型はObject、値 (構造体) を継承しないと思います。それらはボックス化する必要があります。Sessionコレクションには、たくさんのオブジェクトがあり、何でもそこにある可能性があると書かれています。(タイプキャストまたは is キーワードによって) 要求しない限り、ランタイムはチェックを試みません。(コンパイラについては以下で詳しく説明します)

その foreach の var は、この変数 (項目) が Session 列挙子が返す型であるべきだと言っています。異なるタイプを指定するほとんどの場合、タイプキャストのようなものがあります。

何かがクラスまたはボックス (つまり、それがオブジェクトであることを意味します) であるからといって、コンパイラーがそのオブジェクトが実際に何であるかを認識しているとは限りません。実際、標準では、何かがオブジェクトになった場合、実際の型がわかっている場合でも、コンパイラはそれを自動変換してはならないことが示唆されていると思います(おそらく、上記の数行からわかっています)

于 2013-03-09T02:03:45.073 に答える