为什么重载方法不同于ref仅符合CLS

时间:2012-09-26 08:54:13

标签: c# cls-compliant

公共语言规范对方法重载非常严格。

  

只允许方法根据参数的数量和类型重载方法,对于通用方法,允许方法的通用参数数量。

根据csc?

,为什么此代码符合CLS(没有CS3006警告)
using System;

[assembly: CLSCompliant (true)]

public class Test {
    public static void Expect<T>(T arg)
    {
    }

    public static void Expect<T>(ref T arg)
    {
    }

    public static void Main ()
    {
    }
}

2 个答案:

答案 0 :(得分:2)

这符合CLS,因为类型不同。重载规则要求满足一个(或多个)标准,而不是同时满足所有标准。

ref T(或out T,它使用相同类型的不同语义)声明对T引用(对于类)或实例的“引用”(在值类型的情况下)。

有关详细信息,请查找Type.MakeByRefType()方法 - 它会创建表示对原始类型的引用的类型,例如对于T,这将返回T&(用C ++表示法)。

答案 1 :(得分:0)

要明确的是,根据MSDN,一般情况下,仅在ref或out或阵列等级中不同的重载方法符合CLS。

您可以通过编写一个简单的非泛型版本来验证编译器是否确实检查了这种特定情况:

using System;

[assembly: CLSCompliant (true)]

public class Test {
    public static void Expect(int arg)
    {
    }

    public static void Expect(ref int arg)
    {
    }

    public static void Main ()
    {
    }
}

但是,您似乎遇到了编译器边缘情况,因为如果添加泛型方法重载,编译器似乎不会抱怨。

我想说这是编译器中的一个错误(就像在这个类似的question中),或者确实有一个更宽松的泛型规范,因为它们是规范的后一个补充。

我会因某种编译器限制而犯错误,因为这个例子也提出了CS3006:

using System;

[assembly: CLSCompliant(true)]

public class Test<T>
{
    public static void Expect(T arg)
    {
    }

    public static void Expect(ref T arg)
    {
    }

    public static void Main()
    {
    }
}

显然将泛型添加到类而不是方法中会引起编译器的注意......