You could use the IsVirtual property:
var isVirtual = typeof(TestClass).GetMethod("Message").IsVirtual;
You could use the IsVirtual property:
var isVirtual = typeof(TestClass).GetMethod("Message").IsVirtual;
var stringType = typeof(string); var props = stringType.GetProperties(); foreach (var prop in props) { foreach (var accessor in prop.GetAccessors()) { Console.WriteLine("Property {0} accessor {1} declared as virtual {2}", prop.Name, accessor.Name, accessor.IsVirtual); } }
GetMethod 不是反射方法时用的么?
如果,用上面的代码,会得到下面异常信息:
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
Or 中
是判断属性下的 Set 或 Get 方法,这种方式不准确,如,
public class TestClass : ITC { public DateTime Date { get; set; } public virtual string Message { get; set; } public Guid Id { get; set; } } public interface ITC { Guid Id { get; set; } }
这样 ID 也会被判断为 True 的。
@Srouni: 大概是这样的代码,你琢磨琢磨自然就出来了。
既然你还问,我慎重起见,稍微写了一小段代码测试。
这样写是没有问题的。
var myType=typeof(TestClass); var prop=myType.GetMethod("Message"); console.writeline(prop.isvirtual);
我写了两个方法,一个非virtual, 一个virtual,测试一为FALSE,一为TRUE。
至于刚刚上面写的for each var prop in props,好象props有可能找不到这个方法,没有更多测试,你自己找找反射的相关属性方法及示例代码看看吧。
原则上来说,在这儿提问,你得到isVirtual这个方法,对于一个程序员来说,基本就够了,不能让回答者帮你把所有事情搞定,这样你不会进步的。
@Srouni: 使用getMethod的话,myType.GetMethod("Id");是空对象。
我不清楚你是已知方法名还是要用遍历的形式,如果是要遍历,应该还有其他方法来分辨是属性还是方法(函数)。
你大叔给你了方案,你也不能照抄啊。你大叔年纪大了,有时难免犯糊涂的。
你把GetMethod修改为GetProperty吧。
此外,你用你大叔的代码后报告的错误很明显,因为Message是Property,用GetMethod自然不能获取到对象,所以会有异常。
在.net里,属性也是方法,不过不能这样获取,属性默认的对应方法名是get_PropertyName和set_PropertyName,所以,把你大叔的代码里里的Message修改为get_Message或set_Message也能解决问题。
使用属性对应的方法时是不安全的(或者不能简单直接使用的),因为属性的get或set可能不同时存在。
大叔给答案总是网上乱抄的,不保证正确性,掉进坑里请自埋...
其实主要是大叔年纪大了,眼花了,把属性看成方法了...
不过对于提问来说,好象差别不大,我记得以前上学的时候,数学作业都是抄同学的,顺便还找出他做错的地方。
@爱编程的大叔: 这种抄法,很牛啊
4.0以上的获取:
PropertyInfo[] properties = entity.GetType().GetProperties() .Where(p => p.GetMethod.IsVirtual).ToArray();
4.0以下的获取:
PropertyInfo[] properties = entity.GetType().GetProperties() .Where(p => p.GetGetMethod().IsVirtual).ToArray();
判断:
var isVirtual = typeof(TestClass).GetProperty("Message").GetGetMethod().IsVirtual;
我刚开始也是复制到这GetGetMethod,以为是网上的代码写错多写了一个Get,没想到微软居然能写出如此名称的函数来。
楼上说了,如果万一属性是WriteOnly的话,这句会报错的。
这个不准确 会把 上面代码中的 ID 判断为 Virtual 。
@Srouni: 试试这个:
typeof(Cat).GetProperty("Message").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; }
@Srouni:
Private Shared Sub Test() Dim myType As Type = GetType(TestClass) Dim props = myType.GetProperties For Each prop In props MessageBox.Show(prop.Name & "--" & prop.GetGetMethod.IsVirtual) Next End Sub Public Class TestClass Public Property id As String Public Property message() As String Public Overridable Property myMethod() As String End Class
Result is:
id -- false
message -- false
myMethod -- true
VB.NET里面Overridable对应C#的Virtual
实测没有问题。
@Srouni:
Private Shared Sub Test() Dim myType As Type = GetType(TestClass) Dim props = myType.GetProperties For Each prop In props MessageBox.Show(prop.Name & "--" & prop.GetGetMethod.IsVirtual & "--" & prop.GetGetMethod.IsFinal) Next End Sub Public Class TestClass Implements ITest Public Property id As Guid Implements ITest.id Public Property message() As String Public Overridable Property myMethod() As String End Class Public Interface ITest Property id As Guid End Interface
Modify code to support Interface property.
It will done.
Result is:
id -- true -- true
message -- false -- false
myMethod -- true -- false