【问题标题】:How can I avoid using a string member name to get a member of an anonymous type?如何避免使用字符串成员名称来获取匿名类型的成员?
【发布时间】:2010-08-03 09:28:20
【问题描述】:

我正在使用以下代码从匿名类型中检索命名成员。有什么方法可以将以下代码转换为使用 lambda 表达式来实现这一点,或者至少允许调用代码使用 lamda,即使“深入”我必须使用字符串?

private T GetAnonymousTypeMember<T>(object anonymousType, string memberName) where T: class 
{
  var anonTypesType = anonymousType.GetType();
  var propInfo = anonTypesType.GetProperty(memberName);
  return propInfo.GetValue(anonymousType, null) as T;
}

添加: 这就是anonymousType 到达的方式。 GetAnonymousTypeMember 方法是类的私有方法,其唯一的公共方法声明如下:

public void PublishNotification(NotificationTriggers trigger, object templateParameters)

我称这个方法为:

PublishNotification(NotificationTriggers.RequestCreated, new {NewJobCard = model});

new {NewJobCard = model} 是作为anonymousType 传递给GetAnonymousTypeMember 的内容。

【问题讨论】:

  • 你想用什么代替?是否有其他方式来指代成员?
  • 类似 GetAnonTypeMember(m => m.Person)
  • 为什么不直接使用m.Person?当方法唯一要做的就是调用 lambda 表达式时,为什么需要在方法中执行此操作?
  • @Guffa,匿名类型被声明为一个对象,它没有像“Person”这样的属性可以访问,它的内容是可变的,所以我没有什么可以转换为访问属性。
  • 如果是动态对象,myObj.Person 就可以了,对吧?但是您试图确保它是某种类型,这就是原因吗?在这种情况下,请使用演员表:(Person)myObj.Person

标签: c# .net


【解决方案1】:
public U GetMemberValue<T, U>(T instance, Expression<Func<T, U>> selector)
{
    Type type = typeof(T);
    var expr = selector.Body as MemberExpression;
    string name = expr.Member.Name;

    var prop = type.GetProperty(name);
    return (U)prop.GetValue(instance, null);
}

将允许做:

string name = GetMemberValue(new { Name = "Hello" }, o => o.Name);

【讨论】:

    【解决方案2】:

    但是你为什么不直接使用动态呢?例如:

    class MyClass
    {
      public int member = 123;
    }
    
    class Program
    {
      static void Main(string[] args)
      {
        MyClass obj = new MyClass();
    
        dynamic dynObj = obj;
        Console.WriteLine(dynObj.member);
    
        Console.ReadKey();
      }
    }
    

    您也可以参与ExpandoObject

    List<dynamic> objs = new List<dynamic>();
    
    dynamic objA = new ExpandoObject();
    objA.member = "marian";
    objs.Add(objA);
    
    dynamic objB = new ExpandoObject();
    objB.member = 123;
    objs.Add(objB);
    
    dynamic objC = new ExpandoObject();
    objC.member = Guid.NewGuid();
    objs.Add(objC);
    
    foreach (dynamic obj in objs)
      Console.WriteLine(obj.member);
    
    Console.ReadKey();
    

    【讨论】:

      【解决方案3】:

      你的意思是这样的?

      private R GetAnonymousTypeMember<T, R>(T anonymousType, Expression<Func<T, R>> e) where T : class
      {
          return e.Compile()(anonymousType);
      }
      
      public void Do()
      {
          var x = new {S = "1", V = 2};
          var v = GetAnonymousTypeMember(x, _ => _.V);
      }
      

      【讨论】:

        【解决方案4】:

        不,当您将对象作为object 类型发送时,该参数没有特定的类型信息。如果要访问对象的成员,则需要使用反射从对象本身获取类型信息。

        使用 lambda 表达式来获取成员会起作用,但这完全没有意义......

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-07-25
          • 2011-11-03
          • 2022-12-18
          • 1970-01-01
          • 1970-01-01
          • 2012-12-17
          • 1970-01-01
          相关资源
          最近更新 更多