【发布时间】:2015-03-06 13:22:05
【问题描述】:
当 CLSCompliant(true) 时,基本规则之一:“运算符不应超载”。 请让我知道,以上陈述是真/假。解释背后的原因。
【问题讨论】:
当 CLSCompliant(true) 时,基本规则之一:“运算符不应超载”。 请让我知道,以上陈述是真/假。解释背后的原因。
【问题讨论】:
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);
【讨论】:
接受的答案很老,但我很确定它不正确。运算符重载符合 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 对此进行了讨论:'许多语言不支持运算符重载。因此,建议重载运算符的类型包含一个辅助方法,该方法具有适当的特定于域的名称,可提供等效功能。'
【讨论】: