C# 什么类型的?
我在代码中定义C# 什么类型的?,c#,types,C#,Types,我在代码中定义类型时遇到了一个问题。让我们从Abc开始 public partial class Abc { public static String AbcName="wtf"; public String Name { get; set; } } 好的,Abc已经完成。这是一堂课后测试的课。我需要返回带有MyClass实例的对象或类型,如下所示 public partial class MyClass { p
类型时遇到了一个问题。让我们从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;
}
请注意,该代码用于表示我的类<真实代码中的code>GetValue
在内部被调用,并且消费代码将永远不会得到类型为MyClass
以外的对象。也就是说,在实际代码中,MyClass
中的每个方法实际上都返回了MyClass
的一个实例。
这里我们看到了条件编译,其中TARGET\u为\u类型
,这就是这个问题的重点
考虑以下测试代码
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_定义为_TYPE
,测试总是在第二行中抛出异常,并带有#if
或#elseif
块。
我认为这是因为类型
或运行时类型
,但我无法定义它。
那么,如何更正它(在GetTypeImpl中)并让它在没有条件编译的情况下始终工作
以下方法受到限制或我所做的没有效果
- 使用
-不起作用BindingFlags.flatteHierarchy
- 通用
声明-不工作MyClass
- 不要使用
实例扭曲类型或对象-你一定是在开玩笑MyClass
- 考虑以下代码:
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);
它显示了你所遇到的问题。您不能通过反射通过描述类的Type
对象访问类Type
的成员,因为MyClass
没有这些成员
您需要使用Type
对象描述类Type
(即a.GetType().GetType()
)通过反射访问其成员(FullName
),并将类型为Type
描述类MyClass
的对象传递给InvokeMember
根据评论,我想在类型为
System.object的对象上发布相同的示例:
object o = new object();
Type ot = o.GetType();
BindingFlags instanceMethod = BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.InvokeMethod;
//prints System.Object
ot.InvokeMember("ToString", instanceMethod, default(Binder), o, null);
//throws an exception,
//as there is obviously also no FullName in class System.Object
ot.InvokeMember("FullName", instanceProperty, default(Binder), o, null);
@肯金:啊!因此它是-thx:)在那里抛出异常,因为y
表示Type
对象,该对象不包含AbcName
。要访问它,您应该使用x
。然而,试着想想哪一行vary=newmyclass(x.GetTypeImpl().target)
确实…至少它在GetTypeImpl
方法中创建了一个不必要的MyClass
实例…而y
最后似乎是MyClass
的包装,它是类型
对象的包装。可能有助于发布引发的异常。是GetValue
应该返回包装对象或包装对象类型的属性值吗?在您的示例中(“AbcName”在Abc
上,“FullName”在Type
上)…您在InvokeMember
中指定目标,即使您试图检索静态字段值。我认为这是一个问题,在这种情况下,您必须通过null
@肯金,我想没有办法了MyClass
和Type
是两个独立的对象,因此它们有绝对独立的Type
对象来描述它们。不能将这两个信息合并为一个对象。除了,可能在a.GetType()
中搜索所有成员,如果没有找到任何内容,则在a.GetType().GetType()
@KenKin中搜索该成员。这与System.Object
完全相同。