tags:

views:

81

answers:

4

I'm using the following code to retrieve named members from an anonymous type. Is there some way I could convert the follwing code to use a lambda expression to achieve this, or at least to allow the calling code to use a lamda, even if 'deep down' I have to use a string?

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;
}

ADDED: This is how anonymousType arrives. The GetAnonymousTypeMember method is private to a class whose only public method is declared as follows:

public void PublishNotification(NotificationTriggers trigger, object templateParameters)

I call this method:

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

That new {NewJobCard = model} is what is passed to GetAnonymousTypeMember as anonymousType.

A: 

No, when you send the object as the type object, there is no specific type information for the parameter. If you want to access the members of the object you need to use reflection to get the type information from the object itself.

Using a lambda expression to get the member would work, but that would be utterly pointless...

Guffa
A: 

You mean something like this?

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);
}
desco
A very awkward way of writing `var v = x.V;`...
Guffa
+1  A: 
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);
}

Will enable to to do:

string name = GetMemberValue(new { Name = "Hello" }, o => o.Name);
Matthew Abbott
+1  A: 

But why don't You just use dynamic? eg:

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();
  }
}

You could also involve 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();
Turek