2011-01-26 2 views
1

Я совершенно новый на C# Generic Classes, так что я не знаю, можем ли мы динамически обновлять общее свойство динамического класса?Обновить общее свойство универсального класса?

Пусть говорят, у меня есть класс

A { long id; long count; } 

Можем ли мы написать расширение, обновлять данное свойство на 1 так

A.AddOne(a => a.id); will change A {id=1, count=1} to A {id=2, count=1} 

and 

A.AddOne(a => a.count); will change A {id=1, count=1} to A {id=1, count=2} 

Любой помогает будет оценен по достоинству!

+1

Каким образом этот класс родовое? – LukeH

+0

Я думаю, что вы действительно запутываете «Generic». Все, что вы пытаетесь сделать, это на самом деле 'lambda' методы (' x => x.id'). Вам нужно будет иметь дело с делегатами 'linq expressions' и' Func'. Больше света на них можно пролить Джон Скит могущественным рыцарем-рыцарем «Линк». – TheVillageIdiot

ответ

5

Если я правильно понял ваш вопрос, вы хотите, чтобы уметь объявлять, какое свойство обновить, указав метод AddOne лямбда-выражения. В этом случае это возможно - вы можете написать метод расширения, который принимает Expression<T>, извлекает из этого выражения выражение доступа к свойствам и использует Reflection для обновления этого свойства на объекте A.

Ниже очень грубый прототип выше:

public static void AddOne<S,T>(this S x, Expression<Func<S,T>> expr) 
{ 
    if (expr.Body.NodeType != ExpressionType.MemberAccess) 
     throw new InvalidOperationException(); 

    MemberExpression memberExpr = expr.Body as MemberExpression; 
    switch (memberExpr.Member.MemberType) 
    { 
     case MemberTypes.Field: 
      { 
       FieldInfo field = memberExpr.Member as FieldInfo; 
       ulong value = Convert.ToUInt64(field.GetValue(x)); 
       ++value; 
       field.SetValue(x, Convert.ChangeType(value, field.FieldType)); 
       break; 
      } 
     case MemberTypes.Property: 
      { 
       PropertyInfo prop = memberExpr.Member as PropertyInfo; 
       ulong value = Convert.ToUInt64(prop.GetValue(x, null)); 
       ++value; 
       prop.SetValue(x, Convert.ChangeType(value, prop.PropertyType), null); 
       break; 
      } 
     default: 
      throw new InvalidOperationException(); 
    } 
} 
Смежные вопросы