2012-01-23 4 views
2

異なる抽象レベルのクラスを作成しようとしています。ここではVectorの例を使用します。インターフェイスよりも派生クラスを返す指定

私の目標は、自分のクラスのユーザーが使用する抽象化のレベルを選択できるということです。つまり、より派生したクラスを使用する場合と使用しない場合があります。

interface IVector 
{ 
    Vector A(); 
} 

interface ISparseVector : IVector 
{ 
    new SparseVector A(); 
} 

今、私は、次のようなクラスを実装:

class Vector : IVector 
{ 
    public Vector A() { return new Vector(); } 
} 

class SparseVector : Vector,ISparseVector 
{ 
    public new SparseVector A() { return new SparseVector(); } 
} 

これは、すべての罰金とダンディです。しかし、基本クラスが以下のような抽象クラスの場合:

abstract class Vector : IVector 
{ 
    public abstract Vector A(); 
} 

class SparseVector : Vector,ISparseVector 
{ 
    public SparseVector A() { return new SparseVector(); } // Hides abstract member. 
} 

派生したメソッドがVectorの抽象メソッドを隠していると言うコンパイルエラーが発生します。これを回避する方法の考えですか?

+0

あなたは、とにかくそれを解決するためのハックがあるかどうかを以下の回答に尋ねました:私は1つを見つけました(一般的な共分散を使用しています)。残念ながら、あなたの戻り値の型があなたの特定のケースでは役に立たないので、クラスを囲んでいます。 –

答えて

6

「戻り型共分散」と呼ばれる機能は、C#の機能ではありません。戻り型共分散は、Animalを返す仮想メソッドを持つことができ、次にそれをキリンを返すメソッドでオーバーライドする機能です。

タイプセーフで、一部の言語にはこの機能(C++など)がありますが、C#ではサポートされていないため、追加する計画はありません。オーバーライドするメソッドはオーバーライドとマークされなければならず、名前、仮パラメータ型、および戻り型と正確に一致する必要があります。

+1

ありがとうございます。どのようにそれを追加する予定はありませんか? –

+0

とにかくそれを解決するために一般的なC#のハックを知っていますか? –

+0

@swejtsys:よくある質問です。サイトで "C#return type covariance"を検索すると、それに関する豊富な情報が見つかります。多分ここから始めてください:http://stackoverflow.com/questions/5709034/does-c-sharp-support-return-type-covariance/5709191#5709191 –

0

まず、抽象コンストラクタを使用できない理由を示すこのスレッドを見てください。

Why can't I create an abstract constructor on an abstract C# class?

その後、あなたは実際には抽象メソッドがあることになっているとして、実装を提供するためにオーバーライドすることができ、あなたのVectorクラスに抽象メソッドを置く必要があります。

+0

A()はコンストラクタではありません。すでに抽象メソッドです。 –

+0

謝罪、誤読、想定される。ただし、パブリックオーバーライドを行うためにSparseVectorにオーバーライドを追加する必要があります。SparseVector A() – 3Pi

+0

抽象メソッド以外の戻り値の型があるため、オーバーライドを追加できません。 –

1

理由は、Vectorクラスの最初の例では、A()メソッドのアクセスレベルを指定していないためです。これはプライベートメソッドであり、これがデフォルトです。このエラーを回避するには、SparseVectorクラスのnewキーワードを使用します。

+0

ありがとう、私は例でいくつかの間違いを犯しました。私はそれを編集します。主な質問はまだ残っています。 –

+0

SparseVectorクラスのA()メソッドでnewキーワードを使用した場合、新しいキーワードを使用している場合は、一般にあなたがしようとしているものにもっと良い方法があります。 – SoWeLie

0

あなたが試している方法で、抽象メソッドとインターフェイスメソッドを混在させることはできません。 'Vector' abstractを宣言してA()の実装をオーバーライドする場合は、抽象クラスから 'Vector A()'をオーバーライドしますが、インターフェイスISparseVector.Vectorは実装されません。 ISparseVectorのタイプ。

あなたのユースケースでは、 'Vector'が抽象である必要はありません。

+0

この例は大幅に簡略化されています。 –

関連する問題