10

ここでは、単純なクラスの階層構造と、次の型制約を持つジェネリックの使用があります。new()

public abstract class Base 
{
}

public class Derived : Base
{
}

public class TestClass
{
    private void DoSomething<T>(T arg) where T : new()
    {
    }

    public void TestMethod()
    {
        Derived d1 = new Derived();
        DoSomething(d1); // compiles

        Base d2 = new Derived();
        DoSomething(d2); // compile error
    }
}

コードは、指定された行でコンパイルに失敗し、次のエラーが発生します。

'Base' は、ジェネリック型またはメソッド 'Foo.DoSomething(T)' でパラメーター 'T' として使用するために、パブリック パラメーターなしのコンストラクターを持つ非抽象型である必要があります

このエラーは明確で理にかなっていますが、 Base(この時点でインスタンス化できる) のすべての派生物がパブリックのパラメーターなしのコンストラクターを持っていることをコンパイラーが理解することを望んでいました。

これはコンパイラにとって理論的に可能でしょうか?

4

2 に答える 2

8

残念ながら、明示的に型を指定する必要があります

DoSomething<Derived>(d2);

理論的には抽象的なものを作成することはできません

于 2013-08-08T13:02:00.113 に答える
2

新しい制約 (C# リファレンス):

新しい制約を使用するには、型を抽象にすることはできません。

呼び出し:

Base d2 = new Derived();
DoSomething(d2);

あなたは実際にやっています:

Base d2 = new Derived();
DoSomething<Base>(d2);

は抽象化されているためBase、コンパイル エラーが発生します。

したがって、明示的にキャストする必要があります。

Base d2 = new Derived();
DoSomething((Derived) d2);

抽象的ではないものを誰かがそこに置くことをコンパイラーにどのように保証できますか?

私が見る唯一の方法は、「must-inherit-to-non-astract」のようなキーワードを取得してから create public must-inherit-to-non-abstract abstract class Base. その後、コンパイラーは、基本インスタンスをメソッドに入れると、それが実際にはサブクラスになり、抽象化されていないためインスタンス化できることを確認できます。

于 2013-08-08T13:02:08.573 に答える