这是我的代码:
public static class s {
public static int Dx(this int i, Action<int> act, Func<int, bool> con) {
if (con(i)) act(i);
return i;
}
}
稍后在我的代码中我做了:
int g = 22;
int false_con = g.Dx(j => j = 11, z => z != 22); // This is 22 which is fine.
int true_con = g.Dx(j => j = 11, z => z == 22); //This is also 22 which should be 11
如何解决这个问题?
答案 0 :(得分:16)
到目前为止给出的答案都不是实际解释。
到目前为止给出的一些答案表明这是因为int是值类型。尝试使用此程序中的int
替换所有object
s。它是否像原始海报所期望的那样开始工作?不。那么它与值类型和引用类型无关。
相反,它与变量的值有关,无论其类型如何。
Mahdi,您的期望是形式参数j
成为正式参数i
的别名,而参数又是本地变量g
的别名,因此,对j
的任何更改也会导致g
更改,因为它们是同一个变量。事实并非如此。 j
,i
和g
是相同值的副本,但具有不同的存储位置,因此改变一个不会改变其他
您在C#中说“此形式参数是此变量的别名”的方式是使用ref
或out
关键字。所以这个程序会做你期望的事情:
delegate void RefAction<T>(ref T t);
...
public static int Dx(ref int i, RefAction<int> act, Func<int, bool> con)
{
if (con(i))
act(ref i);
return i;
}
...
int g = 22;
int false_con = Dx(ref g, (ref int j) => { j = 11; }, z => z != 22);
int true_con = Dx(ref g, (ref int j) => { j = 11; }, z => z == 22);
“ref”关键字表示g
,i
和j
都是同一变量的不同名称。
正如D斯坦利所说,这可能是糟糕的风格。而不是改变方法中的变量,而是返回您希望将其更改为的值,并让调用者决定要变换的变量(如果有)。
答案 1 :(得分:3)
您的代码路径不会因调用Action
而更改,因此程序始终会返回i
。
看起来您希望在第一次调用后将g
更改为11,这是不正确的,因为g的值被复制到j
然后再复制到i
g
而不是引用至g
,意味着public static int Dx(this int i, Func<int, int> act, Func<int, bool> con) {
if (con(i)) return act(i);
return i;
}
int g = 22;
g = g.Dx(j => 11, z => z != 22); /* g is still 22 */
g = g.Dx(j => 11, z => z == 22); /* g is now 11 */
的值不会因您的操作而被修改。
一个选项是返回值,而不是尝试修改它:
{{1}}
答案 2 :(得分:1)
您的代码返回调用它的整数,因此两个案例都返回g
22
。
答案 3 :(得分:0)
您正尝试通过g
更改Action<int> act
的值,对吧?
它不起作用,因为整数是一个基本类型,它作为值传递,而不是作为引用传递,所以你实际上并没有为g赋值。