我在代码中定义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
在内部调用,消费代码永远不会获得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
, 测试总是抛出异常,第二行包含#if
或#elseif
阻止 。
我认为这是因为Type
或RuntimeType
,但我无法定义它。
那么, 如何纠正它(在GetTypeImpl中)并让它始终在没有条件编译的情况下工作 ?
以下方式受到限制或我已完成但没有效果。
BindingFlags.FlattenHierarchy
- 不工作MyClass<T>
声明 - 无法正常工作MyClass
实例扭曲类型或对象 - 你一定是在开玩笑...... 答案 0 :(得分:3)
请考虑以下代码:
Abc a = new Abc { Name = "a" };
Type t = a.GetType();
BindingFlags staticField = BindingFlags.Static |
BindingFlags.Public |
BindingFlags.GetField;
BindingFlags instanceProperty = BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.GetProperty;
//prints a
t.InvokeMember("Name", instanceProperty, default(Binder), a, null);
//prints wtf
t.InvokeMember("AbcName", staticField, default(Binder), a, null);
//throws an exception as there is no member FullName in MyClass
t.InvokeMember("FullName", instanceProperty, default(Binder), a, null);
Type tt = t.GetType();
//prints t.FullName, that is YourNamespace.Abc
tt.InvokeMember("FullName", instanceProperty, default(Binder), t, null);
它显示了你IMO所拥有的问题。您无法通过反映通过描述类Type
的{{1}}类型的对象访问类Type
的成员,因为MyClass
没有这些成员。
您需要使用描述类MyClass
的{{1}}对象(即Type
)通过反射访问其成员(此处为Type
)并传递类型为{的对象{1}}将课程a.GetType().GetType()
描述为FullName
。
根据评论,我想在Type
类型的对象上发布相同的示例:
MyClass