我想创建一个影响已传递对象变量的泛型方法,我真的只想发送它的地址并一般地影响它。我如何实现这样的目标:
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语句。我确信这个问题之前已经得到了解答,但我不知道如何正确地表达我的问题,对此感到抱歉。
答案 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
的定义,我假设value1
,value2
和value3
是字段。
答案 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