Как извлечь значение stati c из параметра типа - PullRequest
0 голосов
/ 05 мая 2020

Код выглядит следующим образом.

  public class One<T> where T : Two {
    public static int Y;  
    static One() {
      // Y is to be initialised with the Z value from T
      // this code does not compile
      // Y = T.Z;
    }
    public int X {  get { return Y; } }
  }

  public class Two {
    public static int Z = 42;
  }

  public class Three {
    public void Main() {
      One<Two> a = new One<Two>();
      Console.WriteLine("X = {0}", a.X); // should say 42
    }
  }

Идея очень проста: инициализировать значение stati c в классе из другого значения c stati в другом классе, переданном как параметр типа. В этом нет ничего «небезопасного», но естественный способ сделать это не компилировать (см. Код).

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

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Flydog дал вам кое-что, что вы могли бы использовать; Я просто хотел сделать небольшую заметку о моих комментариях / jimi / enigmativity:

Такое ощущение, что вы надеетесь в какой-то момент создать подкласс Two и изменить Z; Вы считаете, что если ваш новый класс Three, который имеет stati c Z, равный 43 и производный от Two, используется в сочетании с One, то вы получите .X, равное 43. Проблема заключается в том, что stati c вещи не могут быть отменены; они разрешаются во время компиляции, и они могут выглядеть так, как будто в определенных обстоятельствах происходит переопределение, но на самом деле это перегрузка или скрытие, и компилятор выбирает что-то с определенным именем в определенном порядке из наследования tree

Поскольку stati c вещи не наследуются (и, возможно, в этом нет необходимости, потому что они, следовательно, всегда известны вам, разработчику, во время компиляции), не ожидается, что однажды кто-то создаст подкласс вашего кода и напишет:

One<Four> a = new One<Four>();

И ваш код должен будет подобрать то, что они установили Z, и использовать его. Вы знаете свои Z и можете использовать их соответствующим образом при компиляции, а они знают свои Z и должны использовать их соответствующим образом. Но я понял, к чему ты клонишься с ТЗ ..

0 голосов
/ 05 мая 2020

Похоже, что он должен работать. Затем вы начинаете набирать T.Z и понимаете, что ваша интуиция согласна с компилятором. T - параметр типа, это не полноценный тип-y.

В любом случае, это работает:

static One()
{
    // Y is to be initialised with the Z value from T
    var typeT = typeof(T);
    var zFieldInfo = typeT.GetField("Z");
    Y = (int) zFieldInfo.GetValue(null);
}

Да, он использует отражение, но только когда-либо будет запущен один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...