标题可能不清楚,但请看下面的模式
public abstract class Animal
{
public abstract Dog GetDog { get; }
public abstract Cat GetCat { get; }
}
public class Dog : Animal
{
public override Dog GetDog {
get { return this; }
}
public override Cat GetCat {
get { return null; }
}
}
Run Code Online (Sandbox Code Playgroud)
这被认为是在基类中具有属性,返回派生类型的不良做法.或者我应该做些什么
public abstract AnimalTypeEnum AnimalType { get; }
Run Code Online (Sandbox Code Playgroud)
编辑:根据评论,我想我应该更清楚我想要实现的目标.该类Dog或Cat类的新实例将由基于特定条件的单独函数创建,然后将Animal类型返回给调用者.调用方法将检查返回实例的类型并相应地使用它.
public Animal CreateAnimal(string path)
{
//Process the document in path and create either a new instance of dog or cat
Dog dg = new Dog();
return dg;
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*man 12
如果你只想要你从中获得的动物可以这样做:
public abstract class Animal<T> where T: Animal<T>
{
public T GetAnimal
{
get { return (T)this; }
}
}
public class Dog : Animal<Dog>
{
}
public class Cat : Animal<Cat>
{
}
public class Giraffe : Animal<Giraffe>
{
}
Run Code Online (Sandbox Code Playgroud)
你这样称呼:
var cat = new Cat();
var dog = new Dog();
var giraffe = new Giraffe();
Cat cat2 = cat.GetAnimal;
Dog dog2 = dog.GetAnimal;
Giraffe giraffe2 = giraffe.GetAnimal;
Run Code Online (Sandbox Code Playgroud)
调用方法将检查返回实例的类型并相应地使用它.
这是你的问题.这需要代码气味.你应该能够把它只是一个对象,而不是以不同的方式对待狗和猫.
如果你需要显示任何一种动物的内容,那么ToString在两个类上重写方法,然后只需要调用ToString动物.如果你需要知道狗或猫的名字,那么添加一个Name属性Animal.如果你可能的话,你应该在这里使用多态,这样任何使用该对象的东西都只是一个Animal简单地涉及不同的事情,因为同一方法的不同实现.
如果你真的,确实需要知道Animal是a Dog还是a Cat那么你可以使用is或as运算符; 您不需要添加您在OP中显示的所有代码.
不,你做错了.
更好的方法是使用单一方法.
public abstract Animal getAnimal();
Run Code Online (Sandbox Code Playgroud)
任何派生类都将知道如何返回自己.我希望这是有道理的.但是我不认为你会想要归还动物.没有意义.
Animal dog = new Dog() ;
dog.getAnimal();
Run Code Online (Sandbox Code Playgroud)
混淆吧?
你可以有一个动物/列表数组,遍历集合并检查如下:
if(animal is Dog)
Run Code Online (Sandbox Code Playgroud)
但你还在检查类型.如果你想使用一个基类让它有意义并暴露一个常见的方法.