我尝试做的是创建包含从子项中使用的常用方法的抽象类。因为我需要为孩子们提供一个静态实例引用,所以我做了类似
的事情public abstract class Environment<T> where T : Environment<T> {
private static T s_instance;
public static T Instance {
get {
return (T)s_instance
}
}
}
这样,如果我将在子节点上调用Instance属性,我将获得子实例,而不是将子节点声明为子节点的实例:
public Desert : Environment<Desert> { }
所以如果我这样做
Desert.Instance
我将获得Desert实例及其所有实现和新方法(以及基础中定义的实例)。
让我们说我有2个这样的课:环境和动物
让我们说我的沙漠和丛林是2环境
让我们说我有2只动物的蝎子和狮子。
我想要做的是从Environment访问Animal类的一些属性,而不了解它的实现。
非常愚蠢的例子:
第一个问题是在环境中我需要有一个列表(数组,字典,通用列表......等等)被定义为Animal的列表,然后,填充该列表的沙漠任务将是蝎子和其他人。显然我无法定义具有泛型类型的结构:
protected List<Animal<T>> animalsList = new List<Animal<T>> ();
另一件事是:看到在空的环境中实例化一般动物的动作很常见,我希望我的通用环境可以检查动物是否已经被实例化,如果没有,则实例化一个。问题是因为Animal是通用的,我做不到
if (Animal.Instance == null) {
Instantiate (animalList[Random(0, animalList.Length)]);
}
(请注意,前一个是伪代码)。
我希望我不会太困惑。也许它的整个想法是错的,也许我不能有仿制药,但如果你有任何建议,我们非常欢迎。
谢谢大家 :-)
编辑:为什么是泛型?
因为我试图使用常见操作创建基类,并且因为我需要对子项的实例的静态引用,所以我将基类定义为泛型。同样,如果我这样做,Instance属性需要在基类中声明,但如果它被子节点调用,它将返回子实例。
例子:
public abstract class Environment<T> where T : Environment<T> {
private static T s_instance;
public static T Instance {
get {
return (T)s_instance
}
}
public int CommonMethod () {
return 1;
}
}
和
public class Desert : Environment<Desert> {
public int SandStorm () {
return 12;
}
}
和
public class Jungle : Environment<Desert> {
public int Rain () {
return 200;
}
}
在我的控制器中我可以做到
public class Controller () {
public void CallCommonMethod () {
Console.Write (Desert.Instance.CommonMethod ());
Console.Write (Jungle.Instance.CommonMethod ());
}
public void CallSandStorm () {
Console.Write (Desert.Instance.SandStorm ());
}
public void CallRain () {
Console.Write (Jungle.Instance.Rain ());
}
}
在这种情况下,不允许这样做
public class Controller () {
public void CallCommonMethod () {
Environment.Instance.CommonMethod ();
// or
Environment<T>.Instance.CommonMethod ();
// or similar
}
}
如果我有
public abstract class Environment {
public int CommonMethod () {
return 1;
}
}
和
public class Desert : Environment {
public Desert Instance { get; private set; }
public Desert () {
Instance = this;
}
public int SandStorm () {
return 12;
}
}
和
public class Jungle : Environment {
public Jungle Instance { get; private set; }
public Jungle () {
Instance = this;
}
public int Rain () {
return 200;
}
}
我需要为每个孩子定义实例。可能我很懒,但我认为通用方式会更好。
答案 0 :(得分:2)
您只需添加代码即可在抽象通用基类中创建实例。
public abstract class Environment<T> where T : Environment<T>, new()
{
private static T _instance = new T();
public static T Instance
{
get { return _instance; } // no need to cast here. It's already of type T.
}
public int CommonMethod()
{
return 1;
}
}
public class Desert : Environment<Desert>
{
public int SandStorm()
{
return 12;
}
}
然后根据需要使用。 Desert.Instance.SandStorm()
和Desert.Instance.CommonMethod()
。
使用工厂和/或摆脱单件要求的评论中的建议可能有效,但您已经非常接近您所寻找的。 p>
修改强>
您还可以像这样访问静态Instance
属性:
Environment<Desert>.Instance.CommonMethod();
Environment<Desert>.Instance.SandStorm();
但在指定泛型类型之前,您无法获得Instance
。所以Environment.Instance
不可用。
答案 1 :(得分:1)
对于你的懒惰问题,你可以做这样的事情
public abstract class Environment
{
private static Environment instance;
public static T GetInstance<T>() where T : Environment
{
return (T)instance;
}
}
public class Desert : Environment
{
}
public class class1
{
public void SomeMethod()
{
Environment.GetInstance<Desert>()
}
}
答案 2 :(得分:0)
答案 3 :(得分:0)
为了完整起见,这是我的最终解决方案。请注意,部分部分是伪代码。这只是为了让您了解我的想法。
public abstract class Environment<T> where T : Environment<T> {
private List<Animal> animalList;
private static T s_instance;
public static T Instance {
get {
return (T)s_instance
}
}
public void ToCallInConstructor () {
PopulateTheList ();
if (Animal.Instance == null) {
Instantiate (animalList.Get (defaultAnimal)); // pseudocode
}
}
public int CommonMethod () {
return 1;
}
public abstract void PopulateTheList();
}
和
public abstract class Animal {
public static Animal Instance { get; private set; }
public Animal () {
Instance = this;
}
public static T GetInstance<T>() where T : Animal {
return (T)Instance;
}
}
其他一切都将遵循我在我的问题的编辑部分中所做的例子,其中我解释了为什么是泛型。
非常感谢大家的建议,尤其是Patrick和CoderDennis。 : - )