継承

2017-12-03 16 views
1

が、それは例えば匿名型から継承することは可能ですが、私は今、私はいくつかの新しいを追加することによって、既存のクラスを拡張するクラスを定義したい継承

public interface IFoo{ 
    int A { get; set;} 
    string B { get; set;} 
} 

public interface IBoo : IFoo{ 
    decimal C { get; set;} 
} 

public class Foo: IFoo {...} 

public class Boo: IBoo {...} 

のようないくつかのクラスとインタフェースを持っています同様に、すべてのクラスに適用される特性:

public class Extended<T> : T where T: IFoo 
{ 
    bool D { get; set;} 
} 

のでExtended<Foo>の場合の結果として、Extended<Foo>内部特性は次のようになります

public int A { get; set;} 
public string B { get; set;} 
public bool D { get; set;} 

私は、これはコンパイルエラーになります知っている:

CS0689: Cannot derive form 'T' because it is a type parameter

が、なぜこれが適用されませんの?限り、私は宣言

現在のソリューションで制約を入れていますよう:私はIBooを実装IFooExtendedBooを実装するクラスExtendedFooを作成する必要があり、私の懸念は方法または回避策がある場合は一般的なものを定義することができることですこれらのクラスのすべてを継承して、インタフェースFooを実装します。

は私の質問は、あなたがそのようそれが唯一の変数Tにあなたのタイプを与え、ジェネリッククラスはジェネリック型を継承したり実装していない、あなたが求めているものを行うことはできません明らか

+0

いいえ、できません。タイプシステムはそれを許可しません。これをやろうとして何を達成しようとしていますか? – Enigmativity

+0

[C#8](https://channel9.msdn.com/Blogs/Seth-Juarez/A-Preview-of-C-8-with-Mads-Torgersen)のデフォルトインタフェースの実装と拡張のすべてについて説明しています。 – Theraot

+0

@mjwills私は質問を更新しました。私はすでに現在のソリューションを含んでいましたが、あなたが持っているすべてのクラス(これは200以上のエンティティがあると想像してください)でこれを行う必要があり、 'IFoo'は拡張可能なエンティティ実際にはプロパティを持つことを意図したものではありません。私は、C#でこのような実装があるべきだと信じています。 – Monah

答えて

0

あるホープそれを使うことができます。

public interface IFoo 
{ 
    int A { get; set; } 
    string B { get; set; } 
} 

public class Extended<T> : IFoo where T : IFoo, new() 
{ 
    IFoo foo = new T(); 

    public int A 
    { 
     get { return foo.A; } 
     set { foo.A = value; } 
    } 

    public string B 
    { 
     get { return foo.B; } 
     set { foo.B = value; }  
    } 

    public bool D { get; set; } 
} 
+0

これはコンパイルされません( '{...}'を編集しても) )。 – Enigmativity

+0

":T"、thats allを削除するのを忘れました。 – Haytam

+0

これは実際にはモナド定義の始まりです。 'タスク'、 'IEnumerable '、 'Nullable 'など – Enigmativity

1

仕事は周りのような何かをすることです。実際には匿名型を継承することもできませんが、それは明確な概念です(MS Docs Anonymous Types entry参照)。

C#のジェネリックはclass Generic<T> {}ため、コンパイラは、コードの実装およびタイプを生成するために実行時に使用される単一の不完全型Generic<>(例えばGeneric<string>Generic<int>、...)を生成するように動作します。参照型のコード実装は同じ生成コードを共有します。List<string>およびList<object>は異なる型ですが、同じコードを使用します。 (同じサイズの値型についても同じことが成り立ちますが、この場合は継承については関係ありません)

要件はジェネリック型class Generic<T> : Tです。私はそれから不完全なタイプGeneric<>を生成する方法があると想像することができます。しかし、タイプTはすべて個別のメンバ、仮想メソッドテーブルなどを持つことができます。したがって、各Generic<T>インスタンシエーションのコードは、C++テンプレートの動作と同様に別々に生成する必要があります。

これは現在、C#コンパイラでは不可能です。その理由は、言語ソリューションを設計し、既存の機能とのすべての競合を解決し、実装するためにユースケースが非常に価値があることを誰も見つけられなかったためです。

あなたのデザインを再考することをお勧めします。ジェネリック型と機能(ビジネスロジック)を混ぜ合わせるとすぐに、とにかく慣用的なC#から離れているでしょう。私はそれについてさらに詳しく説明したいと思いますが、あなたの質問はその視点ではxy problemと非常によく似ています。

+0

' '拡張 'を使用したい場合、' 'C''プロパティを見逃してしまいます。シェルでオブジェクトをラップすると、シェルは新しいプロパティをコーディングせずにオブジェクトのプロパティにアクセスできます。 – Monah

+0

プロパティ 'publicオブジェクトTag {get;セット; } 'オブジェクトに関連付けられているデータを格納するクラスです。 – skyoxZ

+0

まだ私の要件を満たしていません。 'Tag'プロパティを持っているときに' DataGridView'に 'Extended 'を表示したいとします。(読み込みをしないと 'Tag'の詳細を表示できません。 'Tag'から読み込むExtendedの内部のプロパティで、' Tag'はオブジェクトから別のものに変化しています。あるいは、リフレクションを使って、回避しようとしている 'Tag'の中のプリミティブプロパティを読み込みます。 – Monah

1

いいえ、C#でジェネリック型パラメータを継承することはできません:たぶん、これはあなたが望むものである

public interface IFoo { 
    int A { get; set;} 
    string B { get; set;} 
} 

public interface IBoo : IFoo{ 
    decimal C { get; set;} 
} 

public class Foo: IFoo {...} 

public class Boo: IBoo {...} 

public class Extended<T> where T : IFoo 
{ 
    T Foo { get; set; } // Work with this property 
    bool D { get; set;} 
}