C# 关于Func<;字符串>;

C# 关于Func<;字符串>;,c#,delegates,C#,Delegates,我要做的是更新I的值。I是一个整数(值类型),它是按值传递的-值的副本传递给构造函数。当您在Main方法上更改它的值时,它不会更改已经传递给类的内容。因此,您无法在上获取更新后的值 如果您有一个包含整数值字段的对象,然后将该对象传递给任何对象,则对该字段的更改将反映在类上。整数是值类型,而不是引用类型。可能问题在于委托绑定到已装箱的整数数据。这就是为什么要将int和委托的计算结果更改为旧的装箱数据 尝试使用接受int的构造函数 但是,是的,整数确实是通过值来传递的,所以这不起作用。 将委托传递给

我要做的是更新I的值。

I是一个整数(值类型),它是按值传递的-值的副本传递给构造函数。当您在Main方法上更改它的值时,它不会更改已经传递给类的内容。因此,您无法在
上获取更新后的值


如果您有一个包含整数值字段的对象,然后将该对象传递给
任何对象,则对该字段的更改将反映在类上。

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

可能问题在于委托绑定到已装箱的整数数据。这就是为什么要将int和委托的计算结果更改为旧的装箱数据

尝试使用接受int的构造函数

但是,是的,整数确实是通过值来传递的,所以这不起作用。 将委托传递给ctor

0
0
类程序
{
静态void Main()
{
int i=0;
whater x=新whater(()=>i.ToString());
控制台写入线(x);
i=1;
控制台写入线(x);
Console.ReadKey();
}
什么课都行
{
公共事务(Func someFunc)
{
this.variable=someFunc;
}
私有Func变量;
公共字符串数据;
公共重写字符串ToString()
{
数据=变量();
返回数据;
}
}
}
输出: 0 一,

或如其他人所示:

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;
        }
    }
 }
类程序
{
静态void Main()
{
var myRefType=新的myRefType();
myRefType.MyInt=0;
var x=新的(myRefType);
控制台写入线(x);
myRefType.MyInt=1;
控制台写入线(x);
Console.ReadKey();
}
什么课都行
{
公共类型(MyRefType MyRefType)
{
this.variable=()=>myRefType.MyInt.ToString();
}
私有Func变量;
公共重写字符串ToString()
{
返回变量();
}
}
类MyRefType
{
公共int MyInt{get;set;}
}
}
产出: 0
1

int
是值类型,意味着每次使用时都会复制它的值,而不是它的引用。实现此功能的最佳方法是围绕int生成引用类型:

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; }
    }
}

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

如果您想要捕获局部变量,那么您将lambda放在了错误的位置。lambda必须在您想要捕获的外部变量上关闭

class IntRef
{
    public int Val;
}
类程序
{
静态void Main()
{
int i=0;
var x=新值(()=>i);
控制台写入线(x);
i=1;
控制台写入线(x);
Console.ReadKey();
}
}
什么课都行
{
私有Func变量;
公共事务(Func Func)
{
this.variable=func;
}
公共重写字符串ToString()
{
返回此.variable().ToString();
}
}

这有意义吗?请看,lambda必须位于声明“i”的位置,因此“i”是lambda的外部变量,因此lambda会看到它的更改。

我要做的是更新i的值。i是一种值类型,因此在第二次使用Console.WriteLine(x)时不会更新它。你需要用新的i值再次实例化任何东西。@Shuhel这是我不想要的。我想让那个类跟踪我更新的变量。只是为了澄清一下,你需要使用一个引用类型的对象,它有一个整型字段,即一个类的实例。你不能将整数包装在结构中,因为你最终会得到同样不想要的结果。是的,所以我必须写()=>等等。每次都很长,好吧,这就是解决方案,但我们不能只通过新的(I)来做吗?Lambda表达式不能访问外部作用域的ref或out参数。这意味着任何定义为包含方法一部分的out或ref变量都是lambda表达式主体内禁止使用的。如果你不使用ref,它是一个值类型,它是被复制的。我想我应该寻找lamdas并委托一些东西来清楚地理解这个概念。@user810576:基本上这就是其他人所建议的:编译器为你生成一个具有int字段的类。局部变量将转换为对该字段的引用。调用委托时,它会查找字段。我们只有两种方式来传递变量,这样它们就可以无限期地挂起:数组和类的字段。(“ref”参数也允许您传递变量,但ref不能长期存在。)任何在多个位置使用同一变量的解决方案通常都会以某种方式生成一个字段。@user810576:这是一个C#in Depth对于理解非常有价值的主题(这并不是说本书的其余部分没有价值,只是这是它真正闪耀的地方之一)。请参阅第五章,并查看关于捕获变量的部分。
class IntRef
{
    public int Val;
}
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();
   }
}