2010-08-03 3 views
4

J'utilise le code suivant pour récupérer des membres nommés d'un type anonyme. Y a-t-il un moyen de convertir le code suivant pour utiliser une expression lambda, ou du moins permettre au code appelant d'utiliser un lamda, même si je dois utiliser une chaîne en profondeur?Comment puis-je éviter d'utiliser un nom de membre de chaîne pour obtenir un membre d'un type anonyme?

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

AJOUTÉE: Voici comment anonymousType arrive. La méthode GetAnonymousTypeMember est privé à une classe dont la méthode publique seulement est déclarée comme suit:

PublishNotification public void (NotificationTriggers déclenchent, templateParameters objet)

J'appelle cette méthode:

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

Ce new {NewJobCard = model} est ce qui est passé à GetAnonymousTypeMember comme anonymousType.

+0

Que voulez-vous utiliser à la place? Y a-t-il une autre façon de faire référence à un membre? –

+0

Quelque chose comme GetAnonTypeMember (m => m.Person) – ProfK

+0

Pourquoi ne pas simplement utiliser m.Person? Pourquoi le besoin de faire cela dans une méthode, alors que la seule chose que ferait la méthode est d'appeler l'expression lambda? – Guffa

Répondre

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

permettra de le faire:

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

Non, lorsque vous envoyez l'objet au type object, il n'y a pas d'informations de type spécifiques pour le paramètre. Si vous voulez accéder aux membres de l'objet, vous devez utiliser la réflexion pour obtenir les informations de type de l'objet lui-même.

En utilisant une expression lambda pour obtenir le membre fonctionnerait, mais ce serait tout à fait inutile ...

0

Vous voulez dire quelque chose comme ça?

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

Une façon très maladroite d'écrire 'var v = x.V;' ... – Guffa

1

Mais pourquoi ne pas utiliser simplement dynamique? par exemple:

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

Vous pouvez également impliquer 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(); 
Questions connexes