【问题标题】:C# Get type of property specified in ActionC#获取Action中指定的属性类型
【发布时间】:2020-12-16 10:41:40
【问题描述】:

我必须创建类似于 Fluent API。我有 DTO: public class Foo { public string Bar {get;set;} }

而且我需要提供一些属性(例如列名):

new MyFluentApi<Foo>().ColumnAttributes(**p => p.Bar**).ColumnName("Some very long column name where are Bar values")

在 ColumnAttributes 中,我需要获取指定属性的类型/名称,但是如何获取?在表达式 p => p.Bar 我得到 Bar 的实际值,但我需要类型

【问题讨论】:

  • ColumnAttributes 是如何定义的?它应该有一个Expression&lt;Func&lt;...&gt;&gt; 类型的参数
  • 如果你确切地指定ColumnAttributes 是什么,这个问题会更好。论据是什么?有些人可能会认出它,但我不认得。一旦我们有了,剩下的就容易了。

标签: c# action gettype


【解决方案1】:

像这样:

public static MyFluentApi<T> ColumnAttributes<T>(this MyFluentApi<T> api,
    Expression<Func<T, object>> selector)
{
    var expression = (MemberExpression)selector.Body; // Assume expression is accessing a member of T
    var prop = (PropertyInfo)expression.Member; // Assume said member is a property
    var type = prop.PropertyType; // Get the type of property

    // Do something with type

    return api;
}

请注意,如果您的 lambda 不是直接属性访问,这将引发异常。

另一种方法是使用类型推断:

public static MyFluentApi<T> ColumnAttributes<T, TProp>(this MyFluentApi<T> api,
    Expression<Func<T, TProp>> selector)
{
    var type = typeof(TProp);

    // Do something with type

    return api;
}

现在这应该适用于任何表达式,无论是否访问属性,这可能是也可能不是您所追求的。

例如,这将毫无例外地运行:

new MyFluentApi<Foo>().ColumnAttributes(p => new object());

【讨论】:

  • 如果我们调用像p =&gt; p.VirtualMethod()这样的虚方法,对象的静态类型是T,而对象的动态类型是TDerived。我们如何使用GetType 访问派生类型?谢谢。
  • @N.Dogac 你的意思是获取运行时类型?您可以直接使用委托,例如Func&lt;T, object&gt;,调用它并在结果上使用GetType()
  • 如果签名是这样的Func&lt;T, TProp&gt;,委托将需要一个类型为 T 的参数,并且委托调用可能在程序中产生副作用。我们可以在不调用委托的情况下实现这一点吗?
  • @N.Dogac 这是MyFluentApi&lt;T&gt;的扩展方法,所以T永远不能是TDerived(除非MyFluentApi&lt;T&gt;是协变接口)。如果TProp 在运行时引用派生类型,则获取该类型的唯一方法是访问该对象并使用反射检查其类型。
猜你喜欢
  • 2011-07-31
  • 2018-08-02
  • 2023-03-26
  • 1970-01-01
  • 2019-09-28
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多