抱歉,我正在查找文档中的System.Type
类型和PropertyInfo
类型,但我似乎找不到我需要的内容。
如何判断属性(或方法或任何其他成员)是否在其声明类中声明virtual
?
例如
class Cat
{
public string Name { get; set; }
public virtual int Age { get; set; }
}
如何判断Age
属性是否已声明为virtual
?
答案 0 :(得分:62)
您可以使用IsVirtual属性:
var isVirtual = typeof(Cat).GetProperty("Age").GetGetMethod().IsVirtual;
答案 1 :(得分:20)
从技术上讲,属性不是虚拟的 - 它们的访问者是。试试这个:
typeof(Cat).GetProperty("Age").GetAccessors()[0].IsVirtual
如果需要,可以使用如下所示的扩展方法来确定属性是否为虚拟属性:
public static bool? IsVirtual(this PropertyInfo self)
{
if (self == null)
throw new ArgumentNullException("self");
bool? found = null;
foreach (MethodInfo method in self.GetAccessors()) {
if (found.HasValue) {
if (found.Value != method.IsVirtual)
return null;
} else {
found = method.IsVirtual;
}
}
return found;
}
如果它返回null
,则该属性没有访问者(应该永远不会发生)或者所有属性访问者都没有相同的虚拟状态 - 至少有一个是一个而一个不是虚拟的。 / p>
答案 2 :(得分:1)
仅IsVirtual不适用于我。告诉我,我所有的非虚拟非空属性都是虚拟的。我不得不结合使用IsFinal和IsVirtual
这就是我最终得到的:
PropertyInfo[] nonVirtualProperties = myType.GetProperties().Where(x => x.GetAccessors()[0].IsFinal || !x.GetAccessors()[0].IsVirtual).ToArray();
PropertyInfo[] virtualProperties = myType.GetProperties().Where(x => !x.GetAccessors()[0].IsFinal && x.GetAccessors()[0].IsVirtual).ToArray();
答案 3 :(得分:0)
如果类从接口继承,则该接口中的所有属性都将标记为虚拟。如果要检查属性是否可重写,则还需要检查IsFinal是否为假
public static bool IsPropertyOverridable(this PropertyInfo propertyInfo)
{
return (propertyInfo.IsGetPropertyVirtual() || propertyInfo.IsSetPropertyOverridable());
}
public static bool IsGetPropertyVirtual(this PropertyInfo propertyInfo)
{
if (false == propertyInfo.CanRead)
{
return false;
}
return propertyInfo.GetGetMethod(nonPublic: true).IsOverridable();
}
public static bool IsSetPropertyOverridable(this PropertyInfo propertyInfo)
{
if (false == propertyInfo.CanWrite)
{
return false;
}
return propertyInfo.GetSetMethod(nonPublic: true).IsOverridable();
}
答案 4 :(得分:0)
如果您正在使用类型T的泛型类,请使用GetProperties方法获取其属性。在这种情况下,我想绕过在将按视图类的值分配给我的实体类的值时,实体框架生成的所有虚拟集合。 GetAccessors()[0] .IsVirtual方法将告诉我该属性是否为虚拟。
var propts = typeof(T).GetProperties();
T model = new T();
foreach (var viewFieldProperty in propts)
{
sourceFieldName = viewFieldProperty.Name;
Type fieldTypeSource = viewFieldProperty.PropertyType;
sourceFieldNameType = fieldTypeSource.ToString();
if(viewFieldProperty.GetAccessors()[0].IsVirtual==false) //bypass virtual collections
{
…
val = entityObject.GetType().GetProperty(viewFieldProperty.Name).GetValue(entityObject, null);
if (val != null) { viewFieldProperty.SetValue(model, val); }
}
}