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注意,当访问器具有冲突的虚拟属性时,这与我的代码所做的事情不同。