C# 为什么我们可以在类外声明委托?这不是反对面向对象的概念吗?

C# 为什么我们可以在类外声明委托?这不是反对面向对象的概念吗?,c#,oop,C#,Oop,根据oops的基本原理,一切都必须在一个类中。那么为什么我们可以在类之外创建委托呢?实际上委托是一种类型(类)。如果可以的话,当您声明委托类型时,它只是一种语法上的糖分 public delegate int PerformCalculation(int x, int y); 委托是一种安全的类型 封装一个方法。 委托类型派生自.NET Framework中的委托类 因此,当您在类外部声明委托时,实际上是在创建一个新类型/类。然后在类中创建一个委托实例 话虽如此,正如@Mehrdad出色地指

根据oops的基本原理,一切都必须在一个类中。那么为什么我们可以在类之外创建委托呢?

实际上委托是一种类型(类)。如果可以的话,当您声明委托类型时,它只是一种语法上的糖分

public delegate int PerformCalculation(int x, int y);
委托是一种安全的类型 封装一个方法。 委托类型派生自.NET Framework中的委托类

因此,当您在类外部声明委托时,实际上是在创建一个新类型/类。然后在类中创建一个委托实例

话虽如此,正如@Mehrdad出色地指出的那样,所有内容都必须在类内并不是OOP的要求。

这不是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));
//一个“加法器”,将您给它的值与当前值相加
转换器MakeAdder(整数加数)/“构造函数”
{
返回消息=>
{
加数+=味精;
返回加数;
};
}
//...
var加法器=MakeAdder(100)//现在我有一个加法器对象!
对于(int i=0;i<10;i++)
控制台写入线(加法器(i));

这完全偏离了C#中的lambda是一个类的观点。您可以在类似于语言的方案中执行类似的操作,其中根本不存在“类”或“对象”之类的东西,只存在lambdas。

首先,您对OOP“基础”的概念不是基础。“面向对象”一词的发明者Alan Kay有句名言:

<>我编造了“面向对象”这个术语,我可以告诉你我没有C++。 当然,词汇上的“一切都在一个类中”并不是OOP的基本原则。我甚至不清楚“类”的概念是面向对象编程的基础;“基于类的继承”模式只是嵌入到语言支持中的一种方式,它支持消息传递、数据抽象和实现共享等概念

第二,你暗示C#语言设计人员正试图开发一种符合OOP“基本原理”的语言,这是本末倒置。相反,我们希望开发一种语言,支持大型、多样化的团队在我们的平台上共同开发可版本化、独立、交互的软件组件。OOP恰好是一个很好的方法,所以这就是我们正在做的

我们当然不会试图通过任何方式来制作一种“纯”的OOP语言。我们将从任何范例中获取想法,如果它们支持真实的客户受益场景。C#中有来自OOP、过程编程、函数编程、动态语言等的思想

第三,你的问题在逻辑上不一致。您会问为什么可以在类之外定义委托。但是委托是一个类。代表是一个非常特殊的类;它总是密封的,总是从System.MulticastDelegate继承的,并且总是有相同的成员。但这是一门课。我们给它特殊的语法来说明它是一个非常特殊的类。能够在类之外定义委托类是有意义的

第四,将委托放在类之外是合法的最终原因是这样做非常方便。您认为
Func
EventHandler
应该包含哪些类?那门课是“OOP”吗?根据传统的“OOP”智慧,类应该通过将操作与数据关联来表示概念;您提议的
Func
父类代表的是什么概念类的事物,其操作和数据是什么


不存在此类合理的外部类,也不存在与
Func
的“外部类”相关联的操作或数据。那么,为什么要强迫用户定义一个无用的外部类,只是为了符合某些人对“OOP”含义的错误理解呢?

C#是一种多范式语言,这不是一种纯粹的面向对象语言。

我以前也很想知道这一点,但后来我理解了它直接在名称空间中声明的原因。这是因为当你声明一个委托时,在后台为该委托创建了一个大类。

@Mehrdad-我想他只是指OOP。例如,我们可以提到,委托不属于类。也许这是对问题的作者和提出问题的原因的混淆。它类似于类声明,但数组也是一种类型。为什么我们不能在外部声明它?@vatspoo-当您在类外部声明委托时,实际上是在创建一个新类型/类。您可以创建数组的一个实例。您并不是在真正创建一种新类型的数组,是吗?@manojlds-关于结构?它们是值类型,我们可以在类外声明它们。谢谢你…帮我省去了输入和血压的麻烦!顺便说一句,我最喜欢的现实例子是Linux上的GTK+/GNOME代码。完全是OO编程风格,用C完成。@Harper:Windows也一样!窗口是传递消息/参数的对象。:)是的,但没有回答这个问题。如果问题是“为什么我们可以在C#中创建类外的委托,尽管这违反了OOP(假设它违反了OOP)?”我想说的是“因为C#允许,C#不一定是纯OOP”@Eric-你怎么能说类的概念不是编程的基础?每本书和每个网站都提到类是oop的基础。@Vatsoo:你能发明一种面向对象的语言吗