Pour développer mon commentaire, c'est une façon de réaliser votre tâche avec une approche différente. Vous dites que vous voulez "indiquent des propriétés connexes dans une classe", et que "vous souhaitez utiliser des expressions lambda afin que je puisse passer d'un type fort dans mon attribut du constructeur, et non pas un "la magie de la chaîne". De cette façon, je peux exploiter compilateur le type de la vérification".
Ici est donc un moyen d'indiquer des propriétés liées à l'est au moment de la compilation tapé et n'a pas toute la magie des cordes:
public class MyClass
{
public int EmployeeId { get; set; }
public int EmployeeNumber { get; set; }
}
C'est la classe considérée. Nous voulons indiquer que EmployeeId
et EmployeeNumber
sont liées. Pour un peu de code de la concision, nous allons mettre en œuvre ce type d'alias jusqu'en haut du fichier de code. Il n'est pas nécessaire du tout, mais il ne rendre le code moins intimidant:
using MyClassPropertyTuple =
System.Tuple<
System.Linq.Expressions.Expression<System.Func<MyClass, object>>,
System.Linq.Expressions.Expression<System.Func<MyClass, object>>
>;
Cela rend MyClassPropertyTuple
d'un alias pour un Tuple
deux Expression
s, dont chacun saisit la définition d'une fonction à partir d'un MyClass
à un objet. Par exemple, la propriété des getters sur MyClass
sont de telles fonctions.
Maintenant, nous allons saisir la relation. Ici, j'ai fait une statique sur propery MyClass
, mais cette liste pourrait être définie n'importe où:
public class MyClass
{
public static List<MyClassPropertyTuple> Relationships
= new List<MyClassPropertyTuple>
{
new MyClassPropertyTuple(c => c.EmployeeId, c => c.EmployeeNumber)
};
}
Le compilateur C# sait que nous sommes la construction d'un Tuple
de Expression
s, de sorte que nous n'avons pas besoin des conversions explicites en face de ces expressions lambda - ils sont automatiquement mises en Expression
s.
C'est essentiellement en termes de définition, ceux - EmployeeId
et EmployeeNumber
mentions sont fortement typés et appliquées au moment de la compilation, et le refactoring qui n'propriété renomme devrait être en mesure de trouver ces usages lors d'un changement de nom (ReSharper peut certainement). Il n'y a pas la magie des cordes ici.
Mais bien sûr, nous voulons aussi être en mesure d'interroger les relations au moment de l'exécution (j'assume!). Je ne sais pas exactement comment vous souhaitez le faire si ce code est juste à titre indicatif.
class Program
{
static void Main(string[] args)
{
var propertyInfo1FromReflection = typeof(MyClass).GetProperty("EmployeeId");
var propertyInfo2FromReflection = typeof(MyClass).GetProperty("EmployeeNumber");
var e1 = MyClass.Relationships[0].Item1;
foreach (var relationship in MyClass.Relationships)
{
var body1 = (UnaryExpression)relationship.Item1.Body;
var operand1 = (MemberExpression)body1.Operand;
var propertyInfo1FromExpression = operand1.Member;
var body2 = (UnaryExpression)relationship.Item2.Body;
var operand2 = (MemberExpression)body2.Operand;
var propertyInfo2FromExpression = operand2.Member;
Console.WriteLine(propertyInfo1FromExpression.Name);
Console.WriteLine(propertyInfo2FromExpression.Name);
Console.WriteLine(propertyInfo1FromExpression == propertyInfo1FromReflection);
Console.WriteLine(propertyInfo2FromExpression == propertyInfo2FromReflection);
}
}
}
Le code pour propertyInfo1FromExpression
et propertyInfo2FromExpression
ici j'ai travaillé avec l'utilisation judicieuse de la fenêtre d'observation pendant le débogage, ce qui est habituellement la façon dont je travaille ce qu'un Expression
arbre contient en fait.
L'exécution de cette volonté de produire
EmployeeId
EmployeeNumber
True
True
montrer que l'on peut extraire correctement les détails des propriétés, et (cruciale) ils sont de référence identique à l' PropertyInfo
s obtenus par d'autres moyens. Nous espérons que vous pouvez utiliser ceci en conjonction avec quelle que soit l'approche que vous êtes en train d'utiliser pour spécifier les propriétés d'intérêt au moment de l'exécution.