Find out if a property is declared virtual

前端 未结 5 1627
北荒
北荒 2020-12-25 10:53

Sorry, I am looking up the System.Type type and the PropertyInfo type in the documentation but I can\'t seem to find the thing I need.

How

相关标签:
5条回答
  • 2020-12-25 11:29

    Technically, properties are not virtual -- their accessors are. Try this:

    typeof(Cat).GetProperty("Age").GetAccessors()[0].IsVirtual
    

    If you wanted, you could use an extension method like the following to determine if a property is virtual:

    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;
    }
    

    If it returns null, either the property has no accessors (which should never happen) or all of the property accessors do not have the same virtual status -- at least one is and one is not virtual.

    0 讨论(0)
  • 2020-12-25 11:34

    IsVirtual alone didn't work for me. It was telling me that all my non-virtual non-nullable properties were virtual. I had to use a combination of IsFinal and IsVirtual

    Here's what I ended up with:

    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();
    
    0 讨论(0)
  • 2020-12-25 11:40

    if you are using an generic class of type T then get its properities using the GetProperties method. In this case, I want to bypass any virtual collections that entity framework generates when assign values from by view class to my entity class. The GetAccessors()[0].IsVirtual method will tell me if the property is virtual.

     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); }
                    }
         }
    
    0 讨论(0)
  • 2020-12-25 11:50

    If a class inherits from an interface all of the properties in the interface are marked as virtual. If you want to check if a property is overridable you need to check that IsFinal is false as well

    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();
    }
    
    0 讨论(0)
  • 2020-12-25 11:51

    You could use the IsVirtual property:

    var isVirtual = typeof(Cat).GetProperty("Age").GetGetMethod().IsVirtual;
    
    0 讨论(0)
提交回复
热议问题