7
// interface
public interface IHasLegs { ... }

// base class
public class Animal { ... }

// derived classes of Animal
public class Donkey : Animal, IHasLegs { ... } // with legs
public class Lizard : Animal, IHasLegs { ... } // with legs
public class Snake : Animal { ... } // without legs

// other class with legs
public class Table : IHasLegs { ... }

public class CageWithAnimalsWithLegs {
    public List<??> animalsWithLegs { get; set; }
}

??には何を入れればいいですか?AnimalIHasLegs?の両方から継承するオブジェクトを強制するには Snakeあの檻の中の も も見たくないTable

- - - - - - - 編集 - - - - - - -

皆さんの回答に感謝しますが、ここに問題があります:私が実際にやりたいことはこれです:

public interface IClonable { ... }
public class MyTextBox : TextBox, IClonable { ... }
public class MyComboBox : ComboBox, IClonable { ... }

TextBox/ComboBox はもちろん Control です。ここで、Control と IClonable の両方を継承する抽象クラスを作成すると、必要な TextBox/ComboBox の継承が失われます。複数のクラスの継承は許可されていないため、インターフェイスを操作する必要があります。もう一度考えてみると、IClonable から継承する別のインターフェイスを作成できます。

public interface IClonableControl : IClonable { ... }
public class MyTextBox : TextBox, IClonableControl { ... }
public class MyComboBox : ComboBox, IClonableControl { ... }

その後

List<IClonableControl> clonableControls;

ありがとうございました!!

4

6 に答える 6

17

まず第一に、Animalsはクラス名として不適切な選択ですAnimal。クラス名は単数形にする必要があります。このクラスも宣言する必要がありますabstract。これは、Donkey.

次に、およびLeggedAnimalから継承するという名前の抽象クラスを定義できます。そして、などから継承できます。AnimalIHasLegsDonkeyLeggedAnimal

最後に、次のように言うことができList<LeggedAnimal>ます。

于 2013-10-29T14:14:27.610 に答える
10

の直接的な概念はありませんList<T where T : Animals, IHasLegs>Tレベルを上げてケージに移動できますが、呼び出し元はT両方の制約を満たす個体を指定する必要があります。

class Cage<T> where T : Animal, IHasLegs {
    public List<T> Items {get;set;}
}

Cage<Lizard>たとえば、または (個別に) a である可能Cage<Donkey>性がありますが、これを脚のあるものを格納するために使用することはでき ませんでした。つまり、この概念を使用してaと aを同じケージにAnimal入れることはできませんでした。LizardDonkey

于 2013-10-29T14:15:22.803 に答える
3
  1. Animal は抽象クラスなので、IAnimal と呼ぶ必要があると思います。
  2. IhasLegs と IAnimal の両方を継承する新しい型 IAnimalWithLegs を作成します。
  3. 新しく作成したタイプをリストのタイプとして使用します。
于 2013-10-29T14:15:00.843 に答える
3

AnimalwithLegs クラスを作ってみませんか?

public abstract class AnimalWithLegs : Animal, IHasLegs{}

それから

public class CageWithAnimalsWithLegs 
{
   public List<AnimalWithLegs>  AnimalWithLegs { get; set; }
}
于 2013-10-29T14:18:05.703 に答える
1

完全な例を教えてください..コピーしてVisual-Studioに貼り付けてコンパイルします。幸運を :)

 internal class Program
    {
        // interface
        public interface IHasLegs {}

        // base class
        public class Animal {}

        public class AnimalWithLegs : Animal, IHasLegs {}

        // Animals
        public class Donkey : AnimalWithLegs {}

        public class Lizard : AnimalWithLegs {}

        public class Snake : Animal {}

        // example of inanimte objects. (lifeless)
        public class Table : IHasLegs {}

        public class Desk : Table {}

        public class ConferenceTable : Table {}

        //public class Wife : BrainLessObject{} //hmm.. wrong place.. dilemma..

        //example for cages
        public class ListOfIhasLegs : List<IHasLegs> {}

        public class ListOfAnimals : List<Animal> {}

        public class ListOfAnimalsWithLegs : List<AnimalWithLegs> {}

        // usage examples.
        private static void Main(string[] args)
        {
            var donkeyInstance = new Donkey();
            var lizardInstance = new Lizard();
            var snakeInstance = new Snake();

            var tableInstance = new Table();
            var deskInstance = new Desk();
            var conferenceTalbeInstance = new ConferenceTable();

            var listOfThingsWithLegs = new ListOfIhasLegs
            {
                donkeyInstance,
                lizardInstance,
                tableInstance,
                deskInstance,
                conferenceTalbeInstance
            };

            var listOfAnimals = new ListOfAnimals
            {
                donkeyInstance,
                lizardInstance,
                snakeInstance
            };

            var cageOfAnimalsWithLegs = new ListOfAnimalsWithLegs
            {
                donkeyInstance,
                lizardInstance,
            };
        }

    }
于 2013-10-29T14:40:19.950 に答える
0

関心のある型の組み合わせが妥当な数ある場合の 1 つの方法は、複数のインターフェイスから継承する複合インターフェイスを定義することです。インターフェイスの任意の組み合わせに対して複合インターフェイスを定義し、そのような型をジェネリック パラメータとして使用できます。このアプローチの最大の問題は、IFooBar単純IFooに and iBarand のようなインターフェースがそれ自体のメンバーを宣言しない場合、つまり、のすべてのメンバーを実装IFooおよび実装するクラスを意味する場合でも、そのようなクラスを許可しないことを指定する方法がないことです。キャストされるIBarIFooBarIFooBar彼らがそれを実装していると宣言しない限り。したがって、これらのインターフェースの組み合わせを実装するクラスを定義する前に、どのインターフェースの組み合わせに関心があるかを決定する必要があります。

別のアプローチは、 interface を定義し、ISelf<out T> { T Self {get;}}他の多くのインターフェイス (eg IAnimal) に対しても eg を定義し、egを実装するIAnimalAnd<out T> : IAnimal, ISelf<T> { }任意の型(e​​gも実装する) を持つことです。そのパターンを使用し、 、、およびをサポートすることがわかっているリストが必要な場合、パターンに従ってそれらのことを実行するものはすべて実装されます(インターフェイスは任意の順序でネストできます)。そのタイプの参照がある場合、 が実装され、が実装され、が実装され、 になります。もしもZebraIAnimalIAnimalAnd<Zebra>AnimalIWagTailIMooIGiveMilkAnimalIWagTailAnd<IMooAnd<IGiveMilkAnd<Animal>>>>ititIWagTailit.SelfIMooit.Self.SelfIGiveMilkit.Self.Self.SelfAnimalit通常の方法でパターンを実装すると、上記の参照はすべて同じ object instance を参照しますitが、型は異なります。

このアプローチで役立つのは、このパターンを使用してインターフェイスの任意の組み合わせを実装するオブジェクトを、それらの型のサブセットを表すネストされたインターフェイス型にキャストできることです。このアプローチの最大の問題は、 を実装するオブジェクトが と の両方を実装することが期待されていても、IWagTailAnd<IGiveMilkAnd<Animal>>コンパイラはそれを判断できないことです。オブジェクトが を実装し、そのプロパティが を実装していることを知ることができ、パターンの通常の実装では、オブジェクトのプロパティがそれ自体を参照することを期待するかもしれません(オブジェクトが を実装しなければならないことを意味します) が、コンパイラはそれを知ることができません。IWagTailIGiveMilkIWagTailSelfIGiveMilkSelfIGiveMilk

于 2013-10-29T21:21:49.733 に答える