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
      完全相同。