【发布时间】:2011-09-05 13:36:22
【问题描述】:
根据 oops Fundamentels,所有内容都必须在一个类中。那为什么我们可以在类之外创建委托呢?
【问题讨论】:
-
@Mehrdad - 认为他只是指 OOP。
根据 oops Fundamentels,所有内容都必须在一个类中。那为什么我们可以在类之外创建委托呢?
【问题讨论】:
首先,您关于什么是 OOP“基础”的想法并不是基础。 “面向对象”一词的发明者艾伦凯有句名言:
我创造了“面向对象”这个术语,我可以告诉你我并没有想到 C++。
当然,词汇上“一切都在一个类中”的想法不是 OOP 的基本原则。我什至不清楚“类”的概念是面向对象编程的基础。 “基于类的继承”模式只是嵌入到对消息传递、数据抽象和实现共享等概念的语言支持的一种方式。
其次,您暗示 C# 语言设计者正试图制作一种符合 OOP 的“基本原理”的语言,这是本末倒置。相反,我们希望创建一种语言,支持大型、多样化的团队在我们的平台上共同开发可版本化、独立、交互的软件组件。 OOP 恰好是实现这一目标的好方法,所以这就是我们正在做的事情。
我们当然不会以任何方式尝试制作“纯”OOP 语言。如果它们支持真实世界的客户受益场景,我们将从任何范例中获取想法。 C# 中的一些想法取自 OOP、过程式编程、函数式编程、动态语言等等。
第三,你的问题在逻辑上是不一致的。你问为什么你可以在一个类之外定义一个委托。但是委托是一个类。代表是一个非常特殊的类;它始终是密封的,它始终从 System.MulticastDelegate 继承,并且始终具有相同的成员。但它是一个类。我们给它特殊的语法来表明它是一种非常特殊的类。能够在类之外定义委托类是有意义的。
第四,将委托放在类之外是合法的最终原因是因为这样做非常方便。你认为Func<T> 或EventHandler 应该进入什么类?那堂课会是“OOP”吗?根据传统的“OOP”智慧,一个类应该通过将操作与数据相关联表示一个概念;你提议的Func<T>父类代表什么概念类的东西,它上面的操作和数据是什么?
不存在这种合理的外部类,也没有与Func<T>的“外部类”相关的操作或数据。那么为什么要强制用户定义一个无用的外部类,只是为了符合某人对“OOP”含义的错误理解?
【讨论】:
实际上委托是一种类型(类)。当你声明一个委托type
时,它只是一个语法糖,如果可以的话public delegate int PerformCalculation(int x, int y);
委托是一种安全的类型 封装了一个方法。 委托类型派生自 .NET Framework 中的 Delegate 类。
http://msdn.microsoft.com/en-us/library/ms173172%28v=vs.80%29.aspx
所以当你在一个类之外声明一个委托时,你实际上是在创建一个新的类型/类。然后在一个类中创建一个委托实例。
话虽如此,就像@Mehrdad 出色地指出的那样,一切都必须在一个类中并不是 OOP 的要求。
【讨论】:
这恰好是 Java 等某些语言中的一种语言选择。
面向对象的编程仅仅意味着使用称为“对象”的实体对问题进行建模,这些实体具有状态和行为。它没有说明你的代码应该去哪里。
事实上,你甚至可以在没有类的情况下创建“对象”。只要返回一个有闭包的委托,你就有了一个对象。
例子:
//An "adder" that adds the value you give it to its current value
Converter<int, int> MakeAdder(int addend) //"constructor"
{
return msg =>
{
addend += msg;
return addend;
};
}
//...
var adder = MakeAdder(100); //Now I have an adder object!
for (int i = 0; i < 10; i++)
Console.WriteLine(adder(i));
C# 中的 lambda 是一个类,这完全不是重点。你可以在像 Scheme 这样的语言中做这样的事情,其中根本不存在“类”或“对象”之类的东西,只有 lambdas。
【讨论】:
C# 是一种多范式语言,而不是纯粹的面向对象语言。
【讨论】:
我之前也想过这个问题,但后来我明白了直接在命名空间内声明它的原因。这是因为当你声明一个委托时,会在后台为该委托创建一个巨大的类。
【讨论】: