1

私はちょうど C# 4.0 の dynamic キーワードをいじっていて、1 つのことに興味がありました。

クラスがあるとしますDynamicWeirdness : DynamicObject

referenceその中には、タイプもあるという名前のフィールドがありdynamicます。そして、referencetypeタイプの名前付きフィールドType

これは私のコンストラクタです:

public DynamicWeirdness(object reference)
{
        this.reference = reference;
        this.referencetype = reference.GetType();
}

私がこれを試してみたら:

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
    if (binder.Name == "GetType" && args.Length == 0)
    {
        result =  referencetype;
        return true;
    }
    result = null;
    return false;
}

オブジェクトを呼び出すGetType()DynamicWeirdness、呼び出しが無視されて返されます{Name = "DynamicWeirdness" FullName = "Dynamic1.DynamicWeirdness"}。なんで?

ToString()、で試しましたがGetHashCode()、同じことが起こります。

4

2 に答える 2

3

DynamicObjectのドキュメントによると:

DynamicObject クラスから派生したクラスに独自のメンバーを追加することもできます。クラスがプロパティを定義し、TrySetMember メソッドもオーバーライドする場合、動的言語ランタイム (DLR) は最初に言語バインダーを使用して、クラス内のプロパティの静的定義を探します。そのようなプロパティがない場合、DLR は TrySetMember メソッドを呼び出します。

DynamicObject は Object から継承するため、Object のメソッドは、TryInvokeMember が呼び出しを処理できないようにします。

于 2011-08-12T14:19:53.197 に答える
2

メソッド、、、GetType()およびToString()GetHashCode()すべてで定義されていますDynamicObject(から継承するためSystem.Object)。.NETがこれらのメソッドを呼び出す場合、それらはオブジェクトで定義されているため、直接呼び出すだけで、への呼び出しをスキップしますTryInvokeMember

のような別のメソッドを呼び出そうとすると、これが実際に動作していることがわかります。onが呼び出されSubstring()ていることがわかります。TryInvokeMemberDynamicWeirdness

別のタイプを返すようにオーバーライドTryInvokeMemberする代わりに、で新しいメソッドをDynamicWeirdness作成するだけです。GetType()DynamicWeirdness

public new Type GetType()
{
    return this.referencetype;
}

GetHashCode()およびについては、仮想としてマークされているため、ToString()これらのメンバーをオーバーライドできます。DynamicWeirdness

于 2011-08-12T14:16:02.030 に答える