ProfK
ProfK

Reputation: 51064

How can I avoid using a string member name to get a member of an anonymous type?

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.

Upvotes: 4

Views: 297

Answers (4)

Wojtek Turowicz
Wojtek Turowicz

Reputation: 4131

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

Upvotes: 1

Matthew Abbott
Matthew Abbott

Reputation: 61589

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

Upvotes: 2

Guffa
Guffa

Reputation: 700322

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...

Upvotes: 0

desco
desco

Reputation: 16782

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

Upvotes: 0

Related Questions