有没有办法在getter中获取属性的类型?比如反射什么的?
public int Age {
get
{
var myType = {code to get property's type};
//do stuff with myType
}
}
因为我对如何实现这一目标感兴趣,所以我尝试研究这个问题。
我们必须注意的第一件事是,属性是方法的语法糖,所以我们根本不应该关心属性。
第二件事是,如果属性实际上是一个方法,那么它的";类型";实际上应该是getter的返回类型。setters返回类型是System.Void
,但您只关心getter,所以我们可以忽略它。
那么我们怎样才能得到调用方法的返回值呢?像这样:
MethodBase.GetCurrentMethod()
现在我们得到一个不提供返回类型的方法库实例,因为它代表两种类型的方法:正则方法和构造函数,后者没有返回类型。
因此,我们可以将其强制转换为方法info并检索返回类型。
(MethodBase.GetCurrentMethod() as MethodInfo)?.ReturnType
现在我们得到当前的方法。但是,写那些乏味的东西,有没有更简单的方法呢?在C++中,我会使用宏来实现这一点,但这不是C++,所以我们必须即兴发挥。
您可以获取当前的StackTrace并检索最后一个调用方法,如下所示:
MethodBase method = new StackTrace(1).GetFrame(0).GetMethod();
将1传递给StackTrace
的构造函数将给我们一个偏移量1(从而跳过堆栈跟踪中的当前方法(,在调用GetFrame
时返回索引0处的调用方法。GetMethod
再次返回MethodBase
,因此我们可以执行以下操作:
(new StackTrace(1).GetFrame(0).GetMethod() as MethodInfo)?.ReturnType;
使用新的StackTrace将构建整个堆栈,但我们只对单个帧感兴趣,所以我们可以调用new StackFrame(1)
来获取最后一帧。这有点高性能,因为我们只关心这一帧,可以跳过其余的。StackTrace
类构建了整个跟踪,只返回一帧,在我看来这是不必要的分配量。
如果现在将其封装到一个静态方法中,则可以从任何位置调用它并检索当前返回类型。
public static class TypeHelper
{
public static Type GetCallerType() => (new StackFrame(1).GetMethod() as MethodInfo)?.ReturnType;
}
您现在可以在您的属性中调用它。
public int Property
{
get
{
Console.WriteLine(TypeHelper.GetCallerType());
return 0;
}
}
调用将把System.Int32
写入控制台。
在.NET Fiddle 上试用
虽然这样做很有趣,但我建议不要这样做。在运行时从反射中获取内容成本高昂,需要花费大量时间。
你仍然没有说明你的实际问题,因为这对我来说就像一个XY问题。但这是一件有趣的事情。也许这对外面的人有帮助。
如果有人想做更多的研究,我用这个答案作为这里提供的答案的参考。
我想明白了。我从另一个问题中找到了获得房产名称的答案,那就是:
var propertyName = MethodBase.GetCurrentMethod().Name.Substring(4);
要获取属性的类型,您可以使用该名称并从该属性所在的类中获取该属性的类型。
var myType = GetType().GetProperty(propertyName)?.PropertyType
您可以使用this.GetType()
,但实际上不需要this
。
现在,我可以在所有属性中使用完全相同的代码,而不必担心它的名称或类型……我可以在具有ANY名称或ANY类型的属性中使用相同的代码。我可以从不同的地方提取值(比如查询字符串(,并在getter之外解析它们,而不是在xxx个属性中的EVERYgetter中编写解析代码。