7

Common Language Specification は、メソッドのオーバーロードに対して非常に厳密です。

メソッドは、パラメーターの数と型に基づいてのみオーバーロードできます。ジェネリック メソッドの場合は、ジェネリック パラメーターの数に基づいています。

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 ()
    {
    }
}
4

2 に答える 2

2

タイプが異なるため、これは CLS に準拠しています。オーバーロードのルールでは、すべての基準が同時に満たされるのではなく、1 つ (または複数) の基準を満たす必要があります。

A ref T(またはout T、同じ型の異なるセマンティクスで同じを使用している) は、T参照 (クラスの場合) またはインスタンス (値の型の場合) への「参照」を宣言しています。

詳細については、Type.MakeByRefType()メソッドを参照してください。元の型への参照を表す型を作成します。たとえば、 a の場合、 this は(C++ 表記で) Ta を返します。T&

于 2012-09-26T09:17:32.297 に答える
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 ()
    {
    }
}

ただし、ジェネリック メソッドのオーバーロードを追加すると、コンパイラは文句を言わないように見えるため、コンパイラのエッジ ケースにヒットしたようです。

これはコンパイラのバグであると言えます(この同様の質問のように)、またはジェネリックは仕様への後の追加であるため、実際にはジェネリックのより緩和された仕様があります。

この例でも 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()
    {
    }
}

どうやら、メソッドではなくクラスにジェネリックを追加すると、コンパイラの注意が高まります...

于 2014-08-12T08:20:36.460 に答える