C#泛型方法影响特定的对象变量

时间:2015-11-09 02:04:53

标签: c# variables generics

我想创建一个影响已传递对象变量的泛型方法,我真的只想发送它的地址并一般地影响它。我如何实现这样的目标:

public class SomeObject() {
   float value1;
   float value2;
   float value3;
}

在另一堂课中:

void Method1() {

   SomeObject obj;

   if(true) {
     Method2(obj.value1);
   }

   if(false) {
     Method2(obj.value2);
   }

}

void Method2(float value) {
   value++;
}

其中第二种方法中的“value”是obj.value1或obj.value2,具体取决于if语句。我确信这个问题之前已经得到了解答,但我不知道如何正确地表达我的问题,对此感到抱歉。

2 个答案:

答案 0 :(得分:1)

您只需要pass by reference,就像这样:

void Method1() {

   SomeObject obj;

   if(true) {
     Method2(ref obj.value1);
   }

   if(false) {
     Method2(ref obj.value2);
   }

}

void Method2(ref float value) {
   value++;
}

根据问题中SomeObject的定义,我假设value1value2value3是字段。

答案 1 :(得分:1)

通过表达式框架可以满足对泛型方法的要求:

private void Increment<T, V>(Expression<Func<T, V>> f, T instance)
{
    Expression.Lambda<Action<T>>(
        Expression.Assign(f.Body, Expression.Increment(f.Body)), 
        f.Parameters[0])
    .Compile()(instance);
}

要递增SomeObject.value1,您可以致电:

Increment(a=>a.value1, SomeObject);

此方法适用于支持增量运算符的任何类型的字段和属性。但请注意,此方法每次调用时都需要动态编译,并且可能比使用引用参数的解决方案慢得多。

更一般地说,人们可以写:

private void Set<T, V>(Expression<Func<T, V>> f, Func<V, V> map, T instance)
{
    V newvalue = map(f.Compile()(instance));
    ParameterExpression pe = Expression.Parameter(typeof(V));
    Expression.Lambda<Action<T, V>>(
        Expression.Assign(f.Body, pe), 
        f.Parameters[0],
        pe)
    .Compile()(instance, newvalue);
}

允许根据当前值进行任意分配:

Set(a=> a.value1, v=>v+1, SomeObject); // SomeObject.value1++;
Set(a => a.value1, v=>v*6, SomeObject); // SomeObject.value1 *= 6
Set(a => a.value2, v=>90, SomeObject); // SomeObject.value2 = 90