C# Language
ダイナミックタイプ
サーチ…
備考
dynamic
キーワードは、コンパイル時に型が分からない変数を宣言します。 dynamic
変数には任意の値を含めることができ、値の型は実行時に変更できます。
「Metaprogramming in .NET」の帳で説明したように、C#にはdynamic
キーワードのバッキングタイプはありません。
dynamic
キーワードによって有効になる機能は、ローカル実行スコープのサイトコンテナ内でCallSite
オブジェクトを生成して使用するコンパイラアクションの賢明なセットです。コンパイラは、プログラマがCallSite
インスタンスを通じて動的オブジェクト参照として認識する内容を管理します。コンパイル時に動的な処理を行うパラメータ、戻り値の型、フィールド、およびプロパティには、動的使用のために生成されたことを示すメタデータが付いていますが、その基になるデータ型は常にSystem.Object
ます。
動的変数の作成
dynamic foo = 123;
Console.WriteLine(foo + 234);
// 357 Console.WriteLine(foo.ToUpper())
// RuntimeBinderException, since int doesn't have a ToUpper method
foo = "123";
Console.WriteLine(foo + 234);
// 123234
Console.WriteLine(foo.ToUpper()):
// NOW A STRING
動的に戻る
using System;
public static void Main()
{
var value = GetValue();
Console.WriteLine(value);
// dynamics are useful!
}
private static dynamic GetValue()
{
return "dynamics are useful!";
}
プロパティを使用した動的オブジェクトの作成
using System;
using System.Dynamic;
dynamic info = new ExpandoObject();
info.Id = 123;
info.Another = 456;
Console.WriteLine(info.Another);
// 456
Console.WriteLine(info.DoesntExist);
// Throws RuntimeBinderException
コンパイル時に不明な特定の型の処理
次の出力と同等の結果が得られます。
class IfElseExample
{
public string DebugToString(object a)
{
if (a is StringBuilder)
{
return DebugToStringInternal(a as StringBuilder);
}
else if (a is List<string>)
{
return DebugToStringInternal(a as List<string>);
}
else
{
return a.ToString();
}
}
private string DebugToStringInternal(object a)
{
// Fall Back
return a.ToString();
}
private string DebugToStringInternal(StringBuilder sb)
{
return $"StringBuilder - Capacity: {sb.Capacity}, MaxCapacity: {sb.MaxCapacity}, Value: {sb.ToString()}";
}
private string DebugToStringInternal(List<string> list)
{
return $"List<string> - Count: {list.Count}, Value: {Environment.NewLine + "\t" + string.Join(Environment.NewLine + "\t", list.ToArray())}";
}
}
class DynamicExample
{
public string DebugToString(object a)
{
return DebugToStringInternal((dynamic)a);
}
private string DebugToStringInternal(object a)
{
// Fall Back
return a.ToString();
}
private string DebugToStringInternal(StringBuilder sb)
{
return $"StringBuilder - Capacity: {sb.Capacity}, MaxCapacity: {sb.MaxCapacity}, Value: {sb.ToString()}";
}
private string DebugToStringInternal(List<string> list)
{
return $"List<string> - Count: {list.Count}, Value: {Environment.NewLine + "\t" + string.Join(Environment.NewLine + "\t", list.ToArray())}";
}
}
動的に有利なのは、新しいタイプのハンドルを追加するだけで、新しいタイプのDebugToStringInternalのオーバーロードを追加する必要があることです。また、手動でタイプにキャストする必要もありません。
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow