【问题标题】:C# constructors as method's arguments?C# 构造函数作为方法的参数?
【发布时间】:2016-01-24 16:01:09
【问题描述】:

我是 C# 脚本的新手。

我正在阅读一些代码,并且在一个类方法中调用了一个函数以添加到一个名为 Listeners 的 Dictionary 实例,如下所示:

public class ......
{
    private Dictionary<string, List<Component>> Listeners = 
        new Dictionary<string, List<Component>>();

    public void AddListener(Component Listener, string NotificationName)
    {
        // Add listener to dictionary
        if (!Listeners.ContainsKey(NotificationName))
            Listeners.Add (NotificationName, new List<Component>());

        // Add object to listener list for this notification
        Listeners[NotificationName].Add(Listener);
    }
}

现在,对 Listeners.Add 的调用似乎有一个构造函数调用

new List<Component>()

作为论据。

我说对了吗?

【问题讨论】:

  • 一些能让你的生活更轻松的事情。首先,方法声明中缺少逗号,对吗?其次,使用camelCaseConvention而不是PascalCaseConvention命名你的局部变量、形式参数和局部变量。对于有经验的 C# 程序员来说,看到一个名为 NotificationName 的正式文件,读起来很奇怪。应该是notificationName。编译器不在乎,但如果你不遵循标准命名约定,你的代码的读者会对你的代码有错误的直觉。
  • 你永远不会有一个 call 作为参数。你要么有调用的返回值,要么有一个函数指针。
  • @ThomasWeller:我对你的评论感到困惑。很明显,argument 是一个调用——或者更确切地说,是一个对象创建;与实参对应的形参的值将是评估对象创建所产生的值。说“参数不是调用,它是评估调用的结果”似乎很奇怪。你会对整数文字说同样的话吗? abc(123) 的参数不是整数文字,它是通过评估整数文字产生的值?这是一个令人毛骨悚然的区别。所有表达式的值就是它们的求值!
  • @ThomasWeller:C# 规范中没有任何地方说调用是call 指令。它说调用是一个表达式,其是调用的结果,它说arguments表达式 i>,它表示实参对应于形参,它表示表达式的值将被复制到形参。参数是表达式。调用是表达式。因此,参数可以是调用。这对我来说似乎很简单。
  • @kain64b:这不是那个问题的重复。这个问题专门关于字典代码。这个问题是关于使用复杂表达式作为参数的一般模式;碰巧是关于字典的,这只是巧合。

标签: c#


【解决方案1】:

现在,似乎是对Listeners.Add的调用...

你的意思是不是我认为是对Listeners[NotificationName].Add的调用。

... 有一个构造函数调用 new List&lt;Component&gt;() 作为参数。我做对了吗?

是的,调用有两个参数。第一个参数是当前方法的形参,第二个参数是对象创建表达式。这些参数在运行时的将是对字符串的引用对新创建对象的引用

这里的操作顺序是,首先评估 receiver,然后生成这些参数值,然后调用 Add 方法并将这些值复制到它的 形式参数和接收者值用作this

代码的含义是“我有一个从名称到东西列表的映射;如果这个映射没有特定名称的映射,则创建一个从名称到空列表的映射东西”。然后第二个Add 调用将一个元素添加到该列表中。

来自对另一个答案的评论:

我无法在该函数调用之外获得实例引用

好吧,您确实可以在下一行再次从地图上重新读取它。但是如果没有一个设备允许您通过评估另一个表达式来获得该值,就像您在这里所做的那样,您是正确的。该表达式只是产生一个值;它不会将任何名称与它相关联,您以后可以使用它。如果您想这样做,那么您需要创建一个局部变量。

【讨论】:

    【解决方案2】:

    不,该调用获取List&lt;Component&gt; 的新实例作为参数。

    与方法不同,构造函数不能被真正引用。虽然您可以将方法引用存储在委托中并稍后调用它,但您不能对构造函数执行相同操作。虽然这在这里或多或少没有实际意义,因为

    Listeners.Add (NotificationName, new List<Component>());
    

    大致意思如下:

    var param1 = NotificationName;
    var param2 = new List<Component>();
    Listeners.Add(param1, param2);
    

    如您所见,创建了一个新列表,并将该新列表传递给 Add 方法。

    【讨论】:

    • 好吧,new List() 是一个构造函数调用对吗?然后此调用生成一个实例,该实例作为函数参数传递。但在第一种情况下,我无法在该函数调用之外获得实例引用。
    猜你喜欢
    • 2019-03-03
    • 2014-05-09
    • 2011-09-04
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多