在 C# 的 getter 中获取属性的类型



有没有办法在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中编写解析代码。

相关内容

  • 没有找到相关文章

最新更新