В C # как вы можете получить доступ к статическому свойству пользовательского типа, не зная тип во время компиляции? - PullRequest
1 голос
/ 31 мая 2011

У меня есть несколько классов, которые все реализуют определенный интерфейс. Я хочу сохранить уникальную строку в каждом классе, которую я могу получить, не создавая объект для этого класса. Я уже просмотрел много постов здесь и не смог найти ответ.

Если я создаю объект для каждого класса, то я просто хочу:

    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);
      }
    }

Но я хочу сделать это без создания объекта. Поэтому я хочу сделать это:

    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
      }
    }

Я что-то упускаю из виду или это просто невозможно?

Причина, по которой я не хочу создавать объект, заключается в том, что я хочу отображать эту строку в начале, когда мне не нужны никакие объекты. Я создаю объект только тогда, когда мне нужно сэкономить место.

Ответы [ 4 ]

3 голосов
/ 31 мая 2011

Здесь очевидно, что m является атрибутом абстрактного базового класса и присваивает новое значение статическим конструкторам ваших производных классов.

Вы также можете использовать 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 и друзей.

2 голосов
/ 31 мая 2011

Отражение - твой друг:

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 для каждого из типов.

0 голосов
/ 31 мая 2011
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);
}
0 голосов
/ 31 мая 2011

Вам нужно использовать Reflection для доступа к этому свойству ....

Как показано ниже (пример)

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

Console.Write("{0}; ", Myfieldinfoa.GetValue(Myfielda));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...