Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 了解某个属性是否声明为虚拟_C#_Reflection - Fatal编程技术网

C# 了解某个属性是否声明为虚拟

C# 了解某个属性是否声明为虚拟,c#,reflection,C#,Reflection,对不起,我正在文档中查找系统.Type类型和属性info类型,但我似乎找不到我需要的东西 如何判断属性(或方法或任何其他成员)是否在其声明类中声明为virtual 例如 class Cat { public string Name { get; set; } public virtual int Age { get; set; } } 如何判断Age属性是否声明为virtual?您可以使用该属性: var isVirtual = typeof(Cat).GetProperty(

对不起,我正在文档中查找
系统.Type
类型和
属性info
类型,但我似乎找不到我需要的东西

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

例如

class Cat
{
    public string Name { get; set; }
    public virtual int Age { get; set; }
}
如何判断
Age
属性是否声明为
virtual

您可以使用该属性:

var isVirtual = typeof(Cat).GetProperty("Age").GetGetMethod().IsVirtual;

从技术上讲,属性不是虚拟的——它们的访问器是虚拟的。试试这个:

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
,要么属性没有访问器(这永远不会发生),要么所有属性访问器都不具有相同的虚拟状态——至少一个是虚拟的,一个不是虚拟的。

如果类从接口继承,则接口中的所有属性都标记为虚拟的。如果要检查属性是否可重写,还需要检查IsFinal是否为false

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

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();

如果您使用的是T类型的泛型类,那么可以使用GetProperties方法获取其属性。在本例中,我希望绕过entity framework在将值从by view类分配给我的entity类时生成的任何虚拟集合。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); }
                }
     }

如果所考虑的属性为“只写”,则此操作将失败。@cdhowie,是的,它将失败。我的示例中没有包含错误检查。另一个重要的注意事项。如果Cat:ICat,并且ICat有年龄{get;set;},则get或set方法将在100%的时间内失败。@aBetterGamer它实际上并没有失败。虚方法和可重写方法之间存在差异。所以这取决于你想决定什么。有关更多详细信息,请参阅。我使用LINQ解决了这个问题:
var isVirtual=prop.GetType().GetProperties().Where(x=>x.GetAccessors().Any(a=>a.isVirtual))
@MichaelCeranski注意,当访问器具有冲突的虚拟属性时,这与我的代码所做的事情不同。