从不同场景中检索到的属性信息之间有什么区别



我有以下类型:

public abstract class Entity<TId>
{
public TId Id { get; set; }
}
public class Country : Entity<int>
{}
public class Language: Entity<int>
{}

我有以下的linq表达式方法:

internal static class ExpressionHelper
{
public static PropertyInfo HasKey<TEntityType, TKey>(Expression<Func<TEntityType, TKey>> keyDefinitionExpression)
{
LambdaExpression lambda = keyDefinitionExpression;
MemberExpression member = (MemberExpression)lambda.Body;
return member.Member as PropertyInfo;
}
}

我调用'GetProperty'来检索属性信息:

PropertyInfo idCountry = typeof(Country).GetProperty("Id");
PropertyInfo idLanguage = typeof(Language).GetProperty("Id");

其中:idCountry != idLanguage

有意义。但它们为什么不同呢?

2)

PropertyInfo countryIdProperty = ExpressionHelper.HasKey<Country, int>(c => c.Id);
PropertyInfo languageIdProperty = ExpressionHelper.HasKey<Language, int>(c => c.Id);

其中:countryIdProperty == languageIdProperty。= =比;为什么它们相同(相等)?

和idCountry != countryIdProperty。= =比;为什么它们不同?


更新:

public static PropertyInfo HasKey<TEntityType, TKey>(Expression<Func<TEntityType, TKey>> keyDefinitionExpression)
{
LambdaExpression lambda = keyDefinitionExpression;
MemberExpression member = (MemberExpression)lambda.Body;

Type callingType = typeof(TEntityType);
PropertyInfo pInfo = member.Member as PropertyInfo;
if (pInfo.ReflectedType != callingType)
{
return callingType.GetProperty(pInfo.Name);
}

return pInfo;
}

这样做安全吗?

由于您使用CountryLanguage类型的反射获得了前两个值,因此您得到了其ReflectedTypes绑定到这些类的实例。

后两个值是通过查看编译后的表达式树获得的。如果您要编写访问这些类之一的Id属性的代码,您将看到它编译为对Entity<int>类的属性的虚拟调用。

int Foo(Country c) => c.Id;
// Compiles to
IL_0000 ldarg.1 
IL_0001 callvirt    Entity <Int32>.get_Id ()
IL_0006 ret

属性访问本身并没有表明它是在不同的类上执行的,所以表达式树中属性的ReflectedTypeEntity<Int32>,而不是CountryLanguage

如果您想要一种更可靠的方法来确定两个属性是否引用相同的有效属性,您可以将MetadataTokenModule属性组合在一起。

Console.WriteLine((idCountry.MetadataToken, idCountry.Module) == (idLanguage.MetadataToken, idLanguage.Module)); // True

相关内容

  • 没有找到相关文章

最新更新