C#语言不需要委托的概念?
C# language doesn't need the concept of delegates?
感谢s 的客观性,尤其是当您选择 C# 语言时。愤怒的反对者,我想我在这里问了一个合理的问题?否则请留下建设性意见。
对于问题...
- C++ 允许简单地传递(通用)函数指针,如下所示:How to pass a generic function pointer as parameter
- Java 为此使用接口 - 从 OO 的角度来看也很优雅,我们只使用基本语言已经提供的东西。
但是,我从未发现将 delegate
设为明确的概念/关键字有任何真正的优势,而不是像 C++ 或 Java 那样仅仅管理回调的概念 - - 通过将函数指针视为 existing 类型系统下的另一种情况。 (P.S。是的,C# 泛型与 C++ 泛型不同,而 Java 具有运行时泛型而不是编译时泛型,但你明白我的意思)。
(抛开所有狂妄自大和教条不谈)为什么 C# 的设计者认为适合为可以称为通用函数指针/回调的常见现有编程概念取一个新名称?如果没有这样的概念,在 C# 中不能更简单地表示委托吗?
免责声明 我看过很多关于 Whosebug 的答案,但没有一个令人满意地回答了为什么设计师认为适合为一些如此基本的东西包含另一个关键字回调处理。
委托不仅仅是一个简单的回调。首先,它既适用于静态方法,也适用于实例方法,调用者不必注意差异。其次,委托不是单一的方法指针。它可以是 "pointer chain",因此调用者可以通过一次调用调用多个回调 - 同样,调用者不必担心是单次调用还是多次调用。
是的,可以从头开始实现相同的机制 - 但可以使用机器代码构建所有内容 - 需要高级语言。
C++ 有来自 C++11 (std::function
) 的 "official" (non-Boost) "full" 委托...在此之前,获取指向成员函数的指针总是有点 hackish... 所以我不认为 C++ 是一个很好的比较 :-) 而且 C++ 可以重载圆括号,所以 "hide" 需要完成的 hack 更容易给程序员使用 std::function
.
的 "simple" 方式
现在...Java...到"correct"(但假设这不是遗漏,而是经过深思熟虑的决定,因此他们没有任何要更正的地方)缺少委托概念 他们首先不得不在 Java 1.1 中引入匿名 classes 然后在 Java 8 中他们引入了函数式接口(作为一个非 Java 程序员,我认为最后一点有点 hackish...元描述接口有一个方法然后在编译时强制执行它...我不太喜欢它...)。这是因为否则所需的样板代码非常多......
让我们从简单的开始... IComparer<>
接口...它是一个只有一个方法的接口,所以它非常类似于委托...
一个简单的实现:
public class MyComparer : IComparer<int>
{
public int Compare(int x, int y)
{
return x.CompareTo(y);
}
}
这里有一个样板行,第一个 (public class MyComparer : IComparer<int>
)。通过引入 C# delegate
,您已经为每次使用委托获得了一行......但是等等!假设您的 "delegate" 需要对 class 的引用 "contains" 它...
public class MyComparer : IComparer<int>
{
public MyClass Target;
public int Compare(int x, int y)
{
return Target.Ascending ? x.CompareTo(y) : y.CompareTo(x);
}
}
现在这个 class 需要是 MyClass
的嵌套 class。请注意,我没有任何反对嵌套 classes...
我们添加了一个新行 (public MyClass Target
)...但是这段代码通常写起来是错误的...您不应该有 public 非只读字段。您可以使用 auto-属性 public MyClass Target { get; set; }
但这也是 C# 3.0 中引入的句法糖...没有它们,样板代码会增加...我更愿意使用 private readonly MyClass Target
.. 但是然后我必须为构造函数添加四行......你想让我为一个委托写多少行? :-)
而且 C#/.NET 委托仍然提供了更大的灵活性:您使用的函数可以有任何名称,因此您可以在同一个 class 中有多个它们... MyComparer
可以已实现为两种方法:
public int CompareAscending(int x, int y) {}
和
public int CompareDescending(int x, int y) {}
无需添加太多代码,或将所有内容拆分为多个(嵌套)classes。
感谢s 的客观性,尤其是当您选择 C# 语言时。愤怒的反对者,我想我在这里问了一个合理的问题?否则请留下建设性意见。
对于问题...
- C++ 允许简单地传递(通用)函数指针,如下所示:How to pass a generic function pointer as parameter
- Java 为此使用接口 - 从 OO 的角度来看也很优雅,我们只使用基本语言已经提供的东西。
但是,我从未发现将 delegate
设为明确的概念/关键字有任何真正的优势,而不是像 C++ 或 Java 那样仅仅管理回调的概念 - - 通过将函数指针视为 existing 类型系统下的另一种情况。 (P.S。是的,C# 泛型与 C++ 泛型不同,而 Java 具有运行时泛型而不是编译时泛型,但你明白我的意思)。
(抛开所有狂妄自大和教条不谈)为什么 C# 的设计者认为适合为可以称为通用函数指针/回调的常见现有编程概念取一个新名称?如果没有这样的概念,在 C# 中不能更简单地表示委托吗?
免责声明 我看过很多关于 Whosebug 的答案,但没有一个令人满意地回答了为什么设计师认为适合为一些如此基本的东西包含另一个关键字回调处理。
委托不仅仅是一个简单的回调。首先,它既适用于静态方法,也适用于实例方法,调用者不必注意差异。其次,委托不是单一的方法指针。它可以是 "pointer chain",因此调用者可以通过一次调用调用多个回调 - 同样,调用者不必担心是单次调用还是多次调用。 是的,可以从头开始实现相同的机制 - 但可以使用机器代码构建所有内容 - 需要高级语言。
C++ 有来自 C++11 (std::function
) 的 "official" (non-Boost) "full" 委托...在此之前,获取指向成员函数的指针总是有点 hackish... 所以我不认为 C++ 是一个很好的比较 :-) 而且 C++ 可以重载圆括号,所以 "hide" 需要完成的 hack 更容易给程序员使用 std::function
.
现在...Java...到"correct"(但假设这不是遗漏,而是经过深思熟虑的决定,因此他们没有任何要更正的地方)缺少委托概念 他们首先不得不在 Java 1.1 中引入匿名 classes 然后在 Java 8 中他们引入了函数式接口(作为一个非 Java 程序员,我认为最后一点有点 hackish...元描述接口有一个方法然后在编译时强制执行它...我不太喜欢它...)。这是因为否则所需的样板代码非常多......
让我们从简单的开始... IComparer<>
接口...它是一个只有一个方法的接口,所以它非常类似于委托...
一个简单的实现:
public class MyComparer : IComparer<int>
{
public int Compare(int x, int y)
{
return x.CompareTo(y);
}
}
这里有一个样板行,第一个 (public class MyComparer : IComparer<int>
)。通过引入 C# delegate
,您已经为每次使用委托获得了一行......但是等等!假设您的 "delegate" 需要对 class 的引用 "contains" 它...
public class MyComparer : IComparer<int>
{
public MyClass Target;
public int Compare(int x, int y)
{
return Target.Ascending ? x.CompareTo(y) : y.CompareTo(x);
}
}
现在这个 class 需要是 MyClass
的嵌套 class。请注意,我没有任何反对嵌套 classes...
我们添加了一个新行 (public MyClass Target
)...但是这段代码通常写起来是错误的...您不应该有 public 非只读字段。您可以使用 auto-属性 public MyClass Target { get; set; }
但这也是 C# 3.0 中引入的句法糖...没有它们,样板代码会增加...我更愿意使用 private readonly MyClass Target
.. 但是然后我必须为构造函数添加四行......你想让我为一个委托写多少行? :-)
而且 C#/.NET 委托仍然提供了更大的灵活性:您使用的函数可以有任何名称,因此您可以在同一个 class 中有多个它们... MyComparer
可以已实现为两种方法:
public int CompareAscending(int x, int y) {}
和
public int CompareDescending(int x, int y) {}
无需添加太多代码,或将所有内容拆分为多个(嵌套)classes。