コードでを定義する際に問題がありType
ます。Abcから始めましょう。
public partial class Abc {
public static String AbcName="wtf";
public String Name {
get;
set;
}
}
よし、Abc
完了。あとはテスト用の授業です。のインスタンスを持つオブジェクトまたは型を返す必要がありますMyClass
。
public partial class MyClass {
public const BindingFlags
Universal=BindingFlags.NonPublic|BindingFlags.Public,
WithObject=Universal|BindingFlags.Instance,
WithClass=WithObject|BindingFlags.Static,
ForGive=Universal|BindingFlags.SetProperty|BindingFlags.SetField,
ForGet=Universal|BindingFlags.GetProperty|BindingFlags.GetField,
ForDo=BindingFlags.InvokeMethod|WithObject|WithClass;
public MyClass GetTypeImpl() {
if(null!=target)
#if TARGET_AS_TYPE
return new MyClass(target as Type??target.GetType());
#else
return new MyClass(target.GetType());
#endif
else
return new MyClass(typeof(object));
}
public object GetValue(String name) {
var invokeAttr=ForGet|WithClass;
var type=(Type)this.GetTypeImpl().target;
return type.InvokeMember(name, invokeAttr, default(Binder), target, default(object[]));
}
public MyClass(object x) {
this.target=x;
}
public object target;
}
コードは私のクラスを表すためのものであることに注意してください。GetValue
in real code は内部的に呼び出され、消費するコードは の型以外のオブジェクトを取得することはありませんMyClass
。つまり、実際のコードでは、 のすべてのメソッドMyClass
が実際に のインスタンスを返しますMyClass
。ここでTARGET_AS_TYPE
、この質問のポイントである を使用した条件付きコンパイルを確認します。
次のテストコードを検討してください
public partial class TestClass {
public static void TestMethod() {
var abc=
new Abc {
Name="xyz"
};
var x=new MyClass(abc);
var abcName=x.GetValue("Name");
var y=new MyClass(x.GetTypeImpl().target);
#if TARGET_AS_TYPE
var wtf=y.GetValue("AbcName");
var fullName=y.GetValue("FullName"); // exception thrown
#else
var fullName=y.GetValue("FullName");
var wtf=y.GetValue("AbcName"); // exception thrown
#endif
}
}
定義するかどうかにかかわらTARGET_AS_TYPE
ず、テストは常に 2 行目の#if
or#elseif
ブロックで例外をスローします。Type
orのせいだと思いますが、RuntimeType
定義できません。それで、それを(GetTypeImplで)修正して、条件付きコンパイルなしで常に機能させる方法は?
次の方法は制限されているか、効果がありません。
- の使用
BindingFlags.FlattenHierarchy
- 機能しない - ジェネリックの宣言
MyClass<T>
- 機能しない - のインスタンスで型やオブジェクトをワープしないで
MyClass
ください - あなたは私をからかっているに違いありません...