abstract class Animal { }
class Mammal : Animal { }
class Dog : Mammal { }
class Reptile : Animal { }
class AnimalWrapper<T> where T : Animal
{
public ISet<AnimalWrapper<T>> Children { get; set; }
}
class Program
{
public static void Main(string[] args)
{
var foo = new AnimalWrapper<Mammal>();
foo.Children = new HashSet<AnimalWrapper<Mammal>>();
var child = new AnimalWrapper<Dog>();
foo.Children.Add(child);
}
}
這顯然不能編譯,因爲foo.Children.Add(child);
如何使泛型類包含一組僅包含其自己的類型或子類型的子集?
我不知道,如果上面的代碼是演示一下我想要做的最明確的方式,所以我會盡量以純解釋英語:
我希望能夠擁有一個類的Children對象在相同泛型類型的ISet
中。因此,如果我也有var child = new AnimalWrapper<Reptile>();
它在編譯時將無法執行foo.Children.Add(child);
,因爲Reptile
不是,也不是從Mammal
繼承。但是,顯然,即使它是派生的,如上所示,它也不起作用。
最終,能夠說出ISet<AnimalWrapper<Animal>> baz = new HashSet<AnimalWrapper<Animal>>();
,然後將new AnimalWrapper<Mammal>()
添加到該集合,並將new AnimalWrapper<Reptile>()
添加到相同的集合。如上所述,他們的孩子將擁有一個屬性Children
,該屬性的類型是ISet<AnimalWrapper<T>>
。
有沒有辦法,或者我只是期望C#太多?哎呀,我迷惑自己。 :)
編輯:好了,我幾乎想通了這一點,沒有AnimalWrapper
,但與基礎IAnimal
接口,它幾乎可以工作:
interface IAnimal { }
abstract class Animal<T> : IAnimal where T : Animal<T>
{
public ISet<T> Children { get; set; }
}
class Mammal : Animal<Mammal> { }
class Dog : Mammal { }
class Reptile : Animal<Reptile> { }
class Frog : Reptile { }
class Program
{
public static void Main(string[] args)
{
var animals = new HashSet<IAnimal>(); // any animal can be in this
var mammal = new Mammal();
animals.Add(mammal);
mammal.Children = new HashSet<Mammal>();
var dog = new Dog();
mammal.Children.Add(dog); // ok! a dog is a mammal
dog.Children = new HashSet<Dog>(); // in theory, OK, but compile time error
// because Dog : Mammal, and Mammal defines Animal<Mammal>, therefore Dog's
// Children is actually ISet<Mammal>, rather than ISet<Dog> (which is what
// I want, recursively apply the T in Animal.
Mammal mammal2 = new Mammal();
dog.Children.Add(mammal2); // should be verboten, but is allowed for the
// same reason above.
}
}
你嘗試鑄造的孩子爲「ATypeImpl」我會嘗試更多的後來解釋一些? –
一旦構建數據結構,您希望如何與數據結構進行交互? – dtb
我認爲這會更容易理解 - 而且很有可能看到它會掉下來 - 如果你使用了更具體的名字。但我會試着稍後再看看...... –