11

私は実行時に関数を追加しようとしています、そのようなもの:

static void Main()
{
 dynamic d = new Duck();
 d.Quack =(Action) (() => Console.WriteLine("1")); //decalre a new method on runtime ??
 d.Quack(); 

}

public class Duck : System.Dynamic.DynamicObject
{
   //...
}

「UserQuery.Duck」には「Quack」の定義が含まれていません

ダイナミックではないので、私はそれを行うことができますか?

真新しいことExpandoObjectが唯一の解決策ですか?

私はすでに私のアヒルのクラスを持っています。どうすればExpandoにすることができますか?-アヒルをエキスパンドのように振る舞わせることはできますか?

4

1 に答える 1

18

既存のタイプに任意のタイプ(関数も含む)のプロパティを追加することはできません。

dynamic d = new Duck();
d.Quack = "Quack";//fails because there is no such property on duck

ただし、ExpandoObjectを使用することはできます。

dynamic d = new ExpandoObject();
d.Quack = (Action)(() => System.Console.WriteLine("1"));
d.Quack(); 

動的タイプの機能と混同しないでください。

void speak(dynamic d)
{
 d.Quack();//this is NOT checked at compile time
}

これで:speak(new Duck());とを実行できます。speak(new Goose());両方の場合はコンパイルして実行しDuckGooseメソッドQuack()がある場合は、そうでない場合は例外が発生します。(あなたが得るのと同じもの)

型に対してメソッド/プロパティを呼び出すと、dynamic実行時にそれが解決されるだけで、コンパイラチェックは行われません。

ExpandoObjectを使用すると、その場でプロパティを作成できます。


コメントに関するあなたの質問に答えるために、私が見ているように、DynamicObjectから継承できる新しいプロパティを作成する機能を必要とする独自のクラスが必要な場合です。このように(このmsdnページから適応):

class DynamicDuck : DynamicObject 
{
      Dictionary<string, object> dictionary
           = new Dictionary<string, object>();
    public int Count
    {
        get
        {
           return dictionary.Count;
        }
     }
    public override bool TryGetMember(
          GetMemberBinder binder, out object result)
    {
          string name = binder.Name.ToLower();
            return dictionary.TryGetValue(name, out result);
    }
    public override bool TrySetMember(
         SetMemberBinder binder, object value)
    {
          dictionary[binder.Name.ToLower()] = value;
          return true;
    }
 }

次に、次のことができます。

dynamic d = new DynamicDuck();
d.firstname = "Gideon";
d.Quack = (Action)(() => System.Console.WriteLine("Quack"));
于 2012-05-09T09:16:33.663 に答える