为什么以下静态功能不起作用?

时间:2013-04-04 13:20:37

标签: c# .net action func

这是我的代码:

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

如何解决这个问题?

4 个答案:

答案 0 :(得分:16)

到目前为止给出的答案都不是实际解释。

到目前为止给出的一些答案表明这是因为int是值类型。尝试使用此程序中的int替换所有object s。它是否像原始海报所期望的那样开始工作?不。那么它与值类型和引用类型无关。

相反,它与变量的值有关,无论其类型如何。

Mahdi,您的期望是形式参数j成为正式参数i别名,而参数又是本地变量g的别名,因此,对j的任何更改也会导致g更改,因为它们是同一个变量。事实并非如此。 jig相同值的副本,但具有不同的存储位置,因此改变一个不会改变其他

您在C#中说“此形式参数是此变量的别名”的方式是使用refout关键字。所以这个程序会做你期望的事情:

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”关键字表示gij都是同一变量的不同名称。

正如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赋值。