2018年10月17日
川俣晶の縁側ソフトウェア技術雑記total 3999 count

C#において、varがstring型を返すメソッドに対してdynamic型を推定する謎の答

Written By: 川俣 晶連絡先

 Twittter上のhttps://twitter.com/leppie/status/1052138293410897920にて、以下のようなC#クイズがありました。

C# quiz

class Program

{

  static void Main()

  {

    Bar("Baz");

    var i = Foo<string>("Baz"); // what is the type of var?

  }

  static void Bar(dynamic d)

  {

    var i = Foo<string>(d); // what is the type of var?

  }

  static T Foo<T>(dynamic d)

  {

    return (T) d;

  }

}

 正解は、1つめのvarはstring型、2つめのvarはdynamic型になります。

 しかし、Foo<string>(d)は絶対にstring型を返すはずです。なぜvar iはstring型にならず、dynamic型になるのでしょうか。

 以上が設問です。

解答編 §

 さーて、ない知恵をひねって答をひねり出してみました。

 この答で何点が付くのかな。

 ともかくひねり出した答を書いてみよう。

 これを解釈するためには、特殊な挙動や解釈は不要です。ドキュメント化されていない特別な振る舞いや、コンパイラのバグを想定する必要もありません。

 これを解釈するための必要な知識はこれだけです。

dynamic (C# リファレンス)より

ただし、dynamic 型の式を含む演算はコンパイラによって解決または型チェックされません。

 つまり、Foo<string>(d)はdynamic 型の式を含む演算であるため、コンパイラが解釈を行いません。ですから、この初期化式には型がありません。しかし、初期化式があればvarによる変数宣言は可能です。では、変数にはどのような型が想定されるのか。dynamic型を当てはめるしかありません。

 そこから逆算すると、このソースは冗長です。はっきり言って型引数は何の関係もありません。以下のように書けば、【必ずstring型を返すと決まっている関数を初期化式に使っているのに変数がdynamic型になってしまう】という現象を再現できます。

class Program

{

    private static string sub(string s)

    {

        return s;

    }

    static void Main(string[] args)

    {

        dynamic d = "";

        var v1 = sub(d);

    }

}

余談 §

 ただし、以下の点には注意が必要です。

 以下のような宣言では、変数はdynamic型になりません。

        var v2 = d as string;

        var v3 = (string)d;

        var v4 = d is string;

 おそらく【dynamic 型の式を含む演算】という説明がポイントです。これは【dynamic 型の式を含む式】ではないのです。たとえば、d as stringであればdは【dynamic 型の式を含む演算】として扱われますが、式全体ではコンパイラによって式が評価されるものと思われます。

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2018年
10月
20日
BlazorでTaskを駆使したソースが動かない・単体で新規作成したプロジェクトでは動く
3days 0 count
total 3855 count
【技術雑記】の前のコンテンツ
2018年
10月
12日
C#で同期メソッドから非同期メソッドを呼び出す
3days 0 count
total 4060 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20181017110130
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.