【问题标题】:Using ref to pass delegate使用 ref 传递委托
【发布时间】:2013-11-17 17:34:53
【问题描述】:

Delegate 是引用类型,但在尝试将其传递给需要 ref 关键字的方法时。

这让我想起了需要在方法中修改 ref 的字符串,因为它们是不可变的,委托是不可变的吗?

这是我的迷你项目:

delegate void MyDel();
static void Main(string[] args)
{
    MyDel _del  = new MyDel(Idle);

    while(true)
    {
        if(_del != null)
            _del();  
            int c = Console.Read();
            AI(c,ref _del);
            Console.Read();
            Console.Read();
        }
    }
}
    static void AI(int c, ref MyDel del) 
    {
        if(c == 'a')
        {
            del = Attack;
        }else if(c == 'i'){
            del = Idle;
        }else if (c == 's'){
            del = SwingSword;
        }
        else if (c == 'w')
        {
            del = Attack;
            del += SwingSword;
        }
        else {
            del = Idle;
        }
    }

如果没有 ref 关键字,我将回到 swap 方法的情况,即事情只发生在方法内部。

谁能告诉我为什么需要通过引用传递委托?

【问题讨论】:

    标签: c# .net reference delegates ref


    【解决方案1】:

    您必须使用 ref 的原因是因为您正在更改 _del 引用的委托。

    将您的代码更改为以下内容,您将不需要 ref 参数:

    static MyDel AI(int c) 
    {
        if(c == 'a')
        {
            return Attack;
        }
        if(c == 'i')
        {
            return Idle;
        }
        if (c == 's')
        {
            return SwingSword;
        }
        if (c == 'w')
        {
            return (MyDel)Attack + SwingSword;
        }
        return Idle;
    }
    

    除非您指定 ref 关键字,否则 C# 不会通过引用传递。但是,由于委托类型的变量的值是对方法的引用,因此传递的值是引用。使用ref 关键字,您将引用传递给变量的存储区,而不是方法,因此可以更改其值。

    如果上一段像泥巴一样清晰,请阅读https://stackoverflow.com/a/8708674/7122,这是一个非常好的解释传递值与传递的参考。

    【讨论】:

    • 好的 这就是我最初拥有的,但不知道使用 Attack + SwingSword 的可能性。你的解释是有道理的,至少对我来说是这样。
    • 有什么理由返回Attack+ SwingSword;在 VS 中显示为错误?我修复了它,声明了一个新的委托并分配了这两种方法,但你显示的似乎是错误的。
    • @fafase 抱歉,我应该在发布之前检查代码。它需要一个强制转换,以便它知道它将 MyDel 添加到 MyDel,而不仅仅是将任何旧方法组添加到另一个。代码已更新。
    • 确实:),现在我们又是朋友了。感谢这一切。
    【解决方案2】:

    这与不变性无关。您正在为在外部作用域中声明的变量分配一个新值,并且您希望外部作用域知道此分配 - 这就是您需要 ref 的原因。

    这对于 any 类型都是正确的。

    *编辑

    “外部范围”实际上并不是最好的术语。 “调用方法的范围”就是我的意思。

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 2017-06-12
      • 2018-05-07
      • 1970-01-01
      • 2010-12-25
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多