关于Func <string> </string>的问题

时间:2011-06-23 21:58:48

标签: c# delegates

class Program
{
    static void Main()
    {
        int i = 0;
        whatever x = new whatever(i);
        Console.WriteLine(x);
        i = 1;
        Console.WriteLine(x);
        Console.ReadKey();
    }

    class whatever
    {
       public whatever(object variable)
       {
           this.variable = () => variable.ToString();
       }

       private Func<string> variable;
       public string data;

       public override string ToString()
       {
           data = variable();
           return data;
       }
}

输出:

0
0

我想要做的就是更新我的价值。

5 个答案:

答案 0 :(得分:6)

如果要捕获局部变量,则将lambda放在错误的位置。 lambda必须在你想要捕获的外部变量上关闭它。

class Program
{
    static void Main()
    {
        int i = 0;
        var x = new Whatever<int>(()=>i);
        Console.WriteLine(x);
        i = 1;
        Console.WriteLine(x);
        Console.ReadKey();
    }
}

class Whatever<T>
{
   private Func<T> variable;
   public Whatever(Func<T> func)
   {
       this.variable= func;
   }
   public override string ToString()
   {
       return this.variable().ToString();
   }
}

这有意义吗?看,lambda必须是声明“i”的地方,因此“i”是lambda的外部变量,因此lambda看到它的变化。

答案 1 :(得分:3)

i是一个整数(值类型),它通过值传递 - 值的副本被传递给任何构造函数。当您在Main方法上更改其值时,它不会更改已传递给类的内容。因此,您无法获得whatever上的更新值。

如果您有一个包含整数值字段的对象,然后将该对象传递给whatever,那么对该字段的更改将反映在该类中。

答案 2 :(得分:1)

问题可能是委托绑定了整数数据。这就是您更改int并将计算结果委托给旧的盒装数据的原因。

尝试使用带有int的构造函数。

但是,是的,因为价值是有效的,所以这是行不通的。 将代表传递给ctor。

class Program
{
        static void Main()
        {
            int i = 0;
        whatever x = new whatever(() => i.ToString());
        Console.WriteLine(x);
        i = 1;
        Console.WriteLine(x);
        Console.ReadKey();
    }

    class whatever
    {
        public whatever(Func<string> someFunc)
        {
            this.variable = someFunc;
        }

        private Func<string> variable;
        public string data;

        public override string ToString()
        {
            data = variable();
            return data;
        }
    }
 }

输出: 0 1

或正如其他人所说:

class Program
{
    static void Main()
    {
        var myRefType = new MyRefType();
        myRefType.MyInt = 0;

        var x = new whatever(myRefType);
        Console.WriteLine(x);
        myRefType.MyInt = 1;

        Console.WriteLine(x);
        Console.ReadKey();
    }

    class whatever
    {
        public whatever(MyRefType myRefType)
        {
            this.variable = () => myRefType.MyInt.ToString();
        }

        private Func<string> variable;

        public override string ToString()
        {
            return variable();
        }
    }

    class MyRefType
    {
        public int MyInt { get; set; }
    }
}

输出: 0 1

答案 3 :(得分:0)

整数是值类型,而不是引用类型。

答案 4 :(得分:0)

int是值类型,意味着每次使用它时都会复制其值,而不是它的引用。使这项工作的最佳方法是在int:

附近制作引用类型
class IntRef
{
    public int Val;
}

您需要始终使用IntRef.Val并传递IntVal本身将保留引用。