繁体   English   中英

在 C# 中,如何在编译时不知道类型的情况下访问用户定义类型的 static 属性?

[英]In C#, how can you access a static property of a user-defined type without knowing the type at compiletime?

我有一些类都实现了某个接口。 我想在每个 class 中存储一个唯一的字符串,而无需为该 class 创建 object。 我已经在这里搜索了很多帖子,但找不到答案。

如果我为每个 class 创建一个 object,那么我想要的只是:

    class X:IBase{ string m = "x";}

    class Y:IBase{string m = "x";}

    class Z:IBase{string m = "x";}

    class interface IBase{ string m;}

    static int Main(){
      IBase[] arr = {new X(), new Y(), new Z()};
      foreach(IBase b in arr){
          Console.WriteLine(b.m);
      }
    }

但我想在不创建 object 的情况下执行此操作。 所以我想这样做:

    class X:IBase{ static string m = "x";}

    class Y:IBase{ static string m = "x";}

    class Z:IBase{ static string m = "x";}

    class interface IBase{ //no static fields allowed}

    static int Main(){
      Type[] arr = {X, Y, Z};
      foreach(Type t in arr){
          Console.WriteLine(t.m); //error, cannot resolve symbol m
      }
    }

我错过了一些明显的东西还是这不可能?

我不想创建 object 的原因是我想在开始时显示这个字符串,而我不需要任何对象。 当我需要节省空间时,我只创建一个 object。

这里显而易见的是让m成为抽象基 class 的属性,并在派生类的 static 构造函数中分配一个新值。

如果您不想 go 简单路线(抽象基类),您也可以为此使用System.Reflection

您还可以将属性添加到您的类并在那里查找值。

这是使用抽象基类的简单路线:

abstract class AbstractBase: IBase { protected static string m = "?"; }

class X: AbstractBase { static X() { m = "x"; }}

class Y: AbstractBase { static Y() { m = "y"; }}

class Z: AbstractBase { static Z() { m = "z"; }}

interface IBase { //no static fields allowed}
}

static int Main(){
  AbstractBase[] arr = {new X(), new Y(), new Z()};
  foreach(AbstractBase t in arr){
      Console.WriteLine(t.m); // :)
  }
}

编辑:我修复了代码示例以消除编译器错误。 很抱歉发布了不太正确的代码。 这样做,我注意到如果不创建对象就无法真正完成foreach循环,因为(与 python 不同) c# 不会让你只引用一个类型并调用它的方法——这就是System.Reflection的工作,因此,正如其他人指出的那样,您将需要查看GetMember和朋友。

反射是你的朋友:

interface IBase { }
class X : IBase { static string m = "x";}    
class Y : IBase { static string m = "y";}    
class Z : IBase { static string m = "z";}

static void Main()
{
    Type[] arr = { typeof(X), typeof(Y), typeof(Z) };
    foreach (Type t in arr)
    {
        FieldInfo fieldInfo = t.GetField("m", 
                BindingFlags.Static | BindingFlags.NonPublic);
        Console.WriteLine(fieldInfo.GetValue(null));
    }
}

注意Type[] arr = {X, Y, Z}; 已更改为Type[] arr = { typeof(X), typeof(Y), typeof(Z) }; 为了获得每种Type的 object 类型。

您需要使用Reflection来访问该属性....

如下所示(示例)

 MyTypeb = typeof(Myfieldb);
    FieldInfo Myfieldinfob = MyTypeb.GetField("field",BindingFlags.NonPublic|BindingFlags.Static);

Console.Write("{0}; ", Myfieldinfoa.GetValue(Myfielda));
Type[] arr = new[] { typeof(X), typeof(Y), typeof(Z) };
foreach(Type t in arr)
{
    FieldInfo fi = t.GetField("m", BindingFlags.Static | BindingFlags.NonPublic);
    // or PropertyInfo pi = t.GetProperty(...);
    string m  = (string)fi.GetValue(null);
    // GetValue(null, null);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM