找出属性是否被声明为虚拟

时间:2010-11-22 08:21:37

标签: c# reflection

抱歉,我正在查找文档中的System.Type类型和PropertyInfo类型,但我似乎找不到我需要的内容。

如何判断属性(或方法或任何其他成员)是否在其声明类中声明virtual

例如

class Cat
{
    public string Name { get; set; }
    public virtual int Age { get; set; }
}

如何判断Age属性是否已声明为virtual

5 个答案:

答案 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); }
                }
     }