当 CLSCompliant(true) 时,运算符不应该重载 C#?

Posted

技术标签:

【中文标题】当 CLSCompliant(true) 时,运算符不应该重载 C#?【英文标题】:When CLSCompliant(true) , Operators should not be overloaded C#? 【发布时间】:2015-03-06 13:22:05 【问题描述】:

当 CLSCompliant(true) 时,基本规则之一:“运算符不应超载”。 请让我知道,以上陈述是真/假。解释背后的原因。

【问题讨论】:

msdn.microsoft.com/en-us/library/2sk3x8a7%28v=vs.71%29.aspx 【参考方案1】:

CLS 代表Common Language Specification。问题是CLS 是所有.NET 语言都支持的IL 功能的子集。简而言之,并非所有 .NET 语言都支持运算符重载。这就是为什么编译器认为它不是CLS compliant

更新 例如 VB.NET 不支持运算符重载。

考虑以下示例:

public struct DateTime 

   public static TimeSpan operator -(DateTime t1, DateTime t2)  
   public static TimeSpan Subtract(DateTime t1, DateTime t2)  

在 C# 中,您可以执行以下操作:

DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
DateTime dt3 = dt2 - dt1;

在 VB.NET 中不允许这样做。在 VB.NET 中,您将使用

DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
DateTime dt3 = dt2.Subtract(dt1);

【讨论】:

为什么不是每种 .NET 语言都支持运算符重载?例子.请 Dim dt1 As ConsoleApplication2.DateTime() Dim dt2 As ConsoleApplication2.DateTime() Dim dt3 As ConsoleApplication2.DateTime() dt3 = dt2 - dt1 显示错误:未定义运算符'-'对于“ConsoleApplication2.DateTime 的一维数组”和“ConsoleApplication2.DateTime 的一维数组”类型。 ConsoleApplication2.DateTime - 定义该结构的位置【参考方案2】:

接受的答案很老,但我很确定它不正确。运算符重载符合 CLS。将运算符重载放在 .NET 程序集的公共接口中是合法的,只是很难从不支持简单语法的 VB.NET 中使用它。

考虑以下 C# 代码。它被标记为符合 CLS。在构建时,编译器会警告两个不同大小写的公共字段(MyTestField/myTestField)不符合 CLS。但是,它不会警告运算符重载,它接受为 OK。

using System;
[assembly: CLSCompliant(true)]

namespace ClassLibrary1

    public class Class1
    
        public int MyTestField;
        public int myTestField;
        public static int operator +(Class1 lhs, Class1 rhs) => lhs.MyTestField + rhs.MyTestField;
    

原因是重载可以在没有运算符重载的语言(如 VB.NET)中使用。 C# 编译器在 IL 中创建一个 op_Addition 方法,可以直接从 VB.NET 调用。

如果我取出第二个 myTestField,然后从 VB.NET 应用程序构建和引用我的类库,则以下代码可以正常工作。它从 VB.NET 调用 + 运算符:

C#

using System;
[assembly: CLSCompliant(true)]

namespace ClassLibrary1

    public class Class1
    
        public int MyTestField;
        public static int operator +(Class1 lhs, Class1 rhs) => lhs.MyTestField + rhs.MyTestField;
    

VB.NET

Imports ClassLibrary1

Module Program
    Sub Main()
        Dim c As Class1 = New Class1 With .MyTestField = 1
        Console.Write(Class1.op_Addition(c, c))
    End Sub
End Module

Microsoft design guidelines 对此进行了讨论:'许多语言不支持运算符重载。因此,建议重载运算符的类型包含一个辅助方法,该方法具有适当的特定于域的名称,可提供等效功能。'

【讨论】:

以上是关于当 CLSCompliant(true) 时,运算符不应该重载 C#?的主要内容,如果未能解决你的问题,请参考以下文章

python 逻辑运算符

Java运算符

Python3中的逻辑运算符与成员运算符

js--运算符与或非 及 if判断条件隐式转换 介绍

Java 基础 之 逻辑运算

三目运算符