Вопрос по static, gettype, c# – C # - как получить доступ к статическому члену класса, учитывая экземпляр этого класса?

8

В C # предположим, что у вас есть объект (скажем,myObject) это экземпляр классаMyClass. Using myObject только, как бы вы получили доступ к статическому членуMyClass?

class MyClass
    {
    public static int i = 123 ;
    }

class MainClass
    {
    public static void Main()
        {
        MyClass myObject = new MyClass() ;
        myObject.GetType().i = 456 ; //  something like this is desired,
                         //  but erroneous
        }
    }
Можете ли вы объяснить, почему вы не можете ссылаться на него более прямо? Здесь немного запаха кода. Erich Mirabal
Мой метод принимает параметр типа Block, но фактический передаваемый аргумент относится к классу одного из несколькихsubclasses блока, и каждый подкласс должен иметь свою собственную копию статического члена (эту роль играет «я» в коде моего вопроса). JaysonFix
(См. Мой отредактированный ответ для примера этого.) Jon Skeet
Да, это похоже на уродливый (и медленный) способ сделать это по сравнению с наличием полиморфного свойства, которое всегда может вернуть соответствующее значение. Jon Skeet
ИМХО, довольно часто лучший ответ на вопрос "Как мне это сделать?" является "не делай этого". Я сильно подозреваю, что это один из тех времен. tnyfst

Ваш Ответ

3   ответа
25

Type type = myObject.GetType();
FieldInfo field = type.GetField("i", BindingFlags.Public |
                                     BindingFlags.Static);
int value = (int) field.GetValue(null);

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

public class MyClass
{
    public virtual int Value { get { return 10; } }
}

public class MyOtherClass : MyClass
{
    public override int Value { get { return 20; } }
}

и т.п.

Тогда вы можете просто использоватьmyObject.Value чтобы получить правильное значение.

Но это должно быть статичным. Я тоже сталкиваюсь с этой проблемой.
С опубликованными деталями это может показаться чрезмерным, поскольку он может просто ссылаться на MyClass.StaticMember. Это действительно имеет значение, только если myObject может иметь более одного класса, и вы не можете знать, какой именно при разработке.
@mireazma: Тогда, согласно моему ответу, вам нужно либо использовать отражение, либо ввести элемент виртуального экземпляра, который переопределяется в каждом подклассе. Система типов .NET просто не имеет своего рода «статический полиморфизм»; Вы ищете.
@ Роберт: Это точно его ситуация, хотя. Смотрите комментарии к вопросу.
@mireazma: Я действительно не понимаю, что вы имеете в виду, я боюсь. Что должно быть статичным?
4

MyClass.i

Чтобы немного проработать, чтобы использовать статический член, вы должны знать о классе. И наличие ссылки на объект не имеет значения. Единственный способ, которым объект будет иметь значение, - это когда у вас будет 2 разных класса, каждый из которых имеет одинаковый вид члена:

class A { public static int i; }
class B { public static int i; }

НоA.i а такжеB.i это совершенно разные поля, между ними нет логической связи. Даже если B наследует от A или наоборот.

& quot; использовать только myObject & quot; ...
Хенк, см. Мой комментарий выше под вопросом. JaysonFix
Йоханнес, я читал это, но не думаю, что это настоящий (изощренный) вопрос.
JaysinFix, в примере, который вы даете, MyClass.i - единственный разумный ответ, может быть, вы можете объяснить это немного лучше? Это требует "почему"?
Я хотел бы иметь возможность получить доступ к статическому члену & code; i & lt; / code & gt; используя только ссылку & lt; code & gt; myObject & lt; / code & gt ;. JaysonFix
10

я добавлю свойство члена, которое дает вам доступ.

class MyClass
{
    private static int _i = 123;

    public virtual int I => _i;
}

Похожие вопросы