【问题标题】:why delegate work as ref? [closed]为什么委派作为裁判工作? [关闭]
【发布时间】:2018-10-03 16:14:47
【问题描述】:

我有程序

    public delegate T Transformer<T>(T arg);
    public class Util
    {
        public static void Transform<T>(T[] values, Transformer<T> t)
        {
            for (int i = 0; i < values.Length; i++)
                values[i] = t(values[i]);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int[] values = { 1, 2, 3 };
            Util.Transform(values, Square); // Hook in Square
            foreach (int i in values)
            Console.Write(i + " "); // 1 4 9
            Console.ReadLine();
        }
        static int Square(int x) => x * x;
    }

为什么 Util.Transform(values, Square) 改变 values[] 数组?它已经像参考变量一样工作。我只是想看看输出结果不会改变名为“values[]”的源数组。

【问题讨论】:

  • 因为您要为其分配新值?
  • “为什么 [...] 改变 values[] 数组?”我猜是因为你是这样实现的? “我可以添加一些参考吗?”你的意思是?是否要更改方法以使其返回一个新数组?
  • 如果您不想更改值,为什么要更改它们?你想要一个只读数组吗?
  • 恐怕你需要比这更好的英语
  • 这不是代理的错,事实是在.Net框架中,all arrays are reference types.

标签: c# delegates ref


【解决方案1】:

你可以这样改变方法:

public class Util
{
    public static T[] Transform<T>(T[] values, Transformer<T> t)
    {
        return values.Select(x => t(x)).ToArray();
    }
}

那么你可以这样称呼它

var result = Utils.Transform(values, Square);

如果你不能改变那个方法,那么你需要在调用之前复制数组:

var result = values.ToArray();
Utils.Transform(result, Square);

【讨论】:

  • 只是想输入类似的内容。最重要的是,您的 Transformer 方法不应该更新您的输入,而是应该创建一个新数组或 (List),用转换后的值填充它并返回。这样你就可以避免你现在有的副作用。副作用不是一个好习惯。为什么这些值会改变?好吧,因为您提供了一组值。您通过数组中的地址直接访问内存中的值,而不是您可能认为的堆栈上。这个解决方案是更好的方法,然后创建原始数组的副本并传入。
  • 我会尝试,但我不需要复制或创建新数组
  • 是的,我知道数组是引用类型。
  • 返回值。Select(x => t(x)).ToArray();为什么我需要那个?这已经是输出数组了。
  • public static T[] Transform(T[] values, Transformer t) { return values.Select(x => t(x)).ToArray(); for (int i = 0; i
猜你喜欢
  • 2013-09-12
  • 2014-04-25
  • 2012-11-09
  • 2013-12-05
  • 2021-08-07
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多