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

时间:2015-03-06 13:22:05

标签: c# c#-2.0

当CLSCompliant(true)时,基本规则之一:"操作符不应该过载"。 请告诉我,以上陈述是真/假。解释背后的原因。

2 个答案:

答案 0 :(得分:2)

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);

答案 1 :(得分:0)

可接受的答案已经很老了,但是我敢肯定这是不正确的。操作员重载符合CLS。在.NET程序集的公共接口中放置运算符重载是合法的,从不支持简单语法的VB.NET中很难使用它。

请考虑以下C#代码。它被标记为符合CLS。在生成时,编译器会警告两个因大小写不同的公共字段(MyTestField / myTestField)不符合CLS。但是,它不会警告操作员过载,可以接受。

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对此进行了讨论:'许多语言不支持运算符重载。因此,建议重载运算符的类型包括具有适当的特定于域的名称的辅助方法,以提供等效的功能。'