C#. NET Core - Свойство ссылочного экземпляра класса? - PullRequest
0 голосов
/ 03 августа 2020

В C# (. NET Core), есть ли простой способ получить ссылку на свойство экземпляра класса из самого класса?

Под этим я подразумеваю если у меня есть класс:

class A {
  public int SomeProp { get; set; }
}

, я бы хотел получить ссылку на SomeProp, как PropertyInfo или аналогичный.

Я знаю, что могу сделать что-то вроде typeof(A).GetProperty("SomeProp"), который работает, но довольно подробен и не является константой (что означает, что я не мог использовать его, например, в атрибуте).

У меня есть сопоставитель, который использует два метода: Func<TInput, TValue> (принимает объект input и возвращает какое-то значение) и Action<TOutput, TValue> (принимает output и возвращаемое значение из предыдущего метода).

Во втором методе я в основном заканчиваю имея их много: (o, v) => o.SomeProp = v и я ищу способ упростить эту часть, чтобы просто иметь возможность предоставить ссылку на само свойство, и я обрабатываю фактическое назначение за кулисами.

В идеале , это будет что-то (это не строка), которое можно поместить в атрибут, чтобы я мог просто пометить eac h метод:

[AssignTo(A.SomeProp)]
public TValue GetValue(TInput in) => in.CalcValue();

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

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

Ответы [ 2 ]

4 голосов
/ 03 августа 2020

Чтобы предотвратить орфографические ошибки / проблемы с переименованием, вы можете использовать выражение nameof, которое производит имя переменной, типа или члена в качестве строковой константы и доступно в C# 6 и более поздних версиях:

[AssignTo(nameof(A.SomeProp))]
public TValue GetValue(TInput in) => in.CalcValue();
2 голосов
/ 03 августа 2020

Лучшее, что вы можете сделать для константы времени компиляции, - это использовать оператор nameof. Итак:

[AssignTo(nameof(A.SomeProp))]
public TValue GetValue(TInput in) => in.CalcValue();

Затем вы можете получить доступ к этому значению через отражение и безопасно использовать метод GetProperty, зная, что строка, переданная в AssignToAttribute, действительно ссылается на реальный объект. Это будет засчитываться в счет использования собственности. Обратной стороной является то, что он не будет проверять, ссылается ли строка на реальное свойство, а не на метод, например.

Но, как я уже сказал, это лучшее, что вы можете сделать во время компиляции, поскольку методы не существуют до того, как они будут скомпилированы (да), поэтому имя, используемое в коде, является единственной «ссылкой», которую вы можете иметь во время компиляции. Если вы используете sh, чтобы иметь более продвинутую проверку для них (чтобы убедиться, что это реальное, назначаемое свойство, определенное для рассматриваемого типа), вам придется написать собственный анализатор Roslyn для AssignToAttribute.

...