Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对象类具有公共无参数构造函数有什么好处?_C#_Object_Abstract Class_Default Constructor - Fatal编程技术网

C# 对象类具有公共无参数构造函数有什么好处?

C# 对象类具有公共无参数构造函数有什么好处?,c#,object,abstract-class,default-constructor,C#,Object,Abstract Class,Default Constructor,我已经尝试了一段时间来确定为什么对象类有一个公共的、无参数的构造函数,或者实际上,为什么它没有标记为抽象 我看不出有必要(明确地)调用对象的公共构造函数的合理情况;我们只对派生类型的构造函数感兴趣 我理解需要在对象中提供一个默认构造函数,为每个其他类型提供一个默认构造函数,它可以隐式或显式调用。当然,这个默认构造函数只需要标记为受保护的,不是吗 我见过人们在线程同步中构造“空对象”;但在这种情况下锁定“真实对象”不是更正确吗 同样,既然对象类公开的功能只对派生类型有用(或静态调用),为什么它不是

我已经尝试了一段时间来确定为什么
对象
类有一个公共的、无参数的构造函数,或者实际上,为什么它没有标记为
抽象

我看不出有必要(明确地)调用
对象的公共构造函数的合理情况;我们只对派生类型的构造函数感兴趣

我理解需要在
对象
中提供一个默认构造函数,为每个其他
类型
提供一个默认构造函数,它可以隐式或显式调用。当然,这个默认构造函数只需要标记为受保护的,不是吗

我见过人们在线程同步中构造“空对象”;但在这种情况下锁定“真实对象”不是更正确吗

同样,既然
对象
类公开的功能只对派生类型有用(或静态调用),为什么它不是一个抽象类?这似乎是一个比拥有一个类更好的设计,这个类给程序员的印象是它可以自己进行有意义的实例化


我怀疑答案可能与CLR的内部工作有关,但我想知道为什么
对象
必须有一个公共构造函数,如果有任何原因不能将其标记为
抽象

,那么很可能与线程同步有关。看

微软使用

private System.Object lockThis = new System.Object();
在他们自己的例子中告诉我,在他们看来,仅仅为了同步而创建一个新对象是完全正确的

而且,Java在其同步示例中允许完全相同的事情,因此微软的开发人员可能只是“仿效”了一种让语言运行的标准方式


当然,在CLR中也可能存在一些秘密的技术原因。

我能想到的一个原因是,为什么不应该将对象抽象化,并且在CLR内部功能中使用它的默认构造函数是在装箱和取消装箱时

检查

此外,线程同步不必使用“真实”对象,因为使用对象的目的是获取锁(一旦线程获取锁,其他所有人都必须等待其释放),而不是锁定对象本身


为了便于论证,如果线程对其工作中的实际对象不感兴趣(可能是它在做一些整数操作),那么它应该使用使用默认构造函数创建的空对象。

当值类型被装箱时,CLR不会创建更专业类的实例吗,例如
System.Int32
System.DateTime
?如果是这样的话,它将调用相关类型的派生构造函数。我指的是问题中提到的“真实对象”,我相信它指的是您使用自己的属性和方法定义的自定义类,而不是framework@BradleySmith不我不这么认为,因为Int32是从System.ValueType派生的,创建一个实例会破坏装箱的目的,实际上,当你使用int时,它使用System.Int32类。我的印象是编译器将值类型的变量转换为等效CLR类型的变量,因此,实际的
ValueType
“类”的实例在值装箱之前不会被创建;没有其他变量。Int、float等是编译器的快捷方式,可以在同一篇MSDN文章中的场景后面为您创建相应的值类型结构:“但实际上,此对象通常表示需要线程同步的资源。”这向我建议,
new object()
主要用于示例代码中,而不是被推荐用于实际场景。事实并非如此
private object\u locker=new object()
通常建议不要使用对象本身(或
this
),因为任何数量的未协调线程都可以访问
this
,然而,
\u locker
的使用更可能是为了明确地用作协作线程之间的同步机制。鉴于到目前为止对该主题的讨论,我很高兴将此标记为公认的答案。如果这一单一目的是
对象
可以实例化的原因,那么这似乎是一个糟糕的设计决策。如果有一个用于线程同步的专用类,听起来像
对象
可能会变得抽象(或者将其公共构造函数拿走)。您不能将构造函数标记为抽象类,尽管您可能想标记该类abstract@RuneFS是的,我就是这个意思。作为使构造函数受到保护的替代方法,使类抽象将得到相同的结果。