创建摘要 类,其中包含要从 children 中使用的常用方法
Create abstract classes that contain common methods to be used from their children
我想做的是创建抽象 classes,其中包含要从他们的 children 使用的常用方法。因为我需要 children 的静态实例引用,所以我正在做类似
的事情
public abstract class Environment<T> where T : Environment<T> {
private static T s_instance;
public static T Instance {
get {
return (T)s_instance
}
}
}
这样,如果我将在 child 上调用实例 属性,我将获得 child 实例,而不是将 child 声明为的抽象实例:
public Desert : Environment<Desert> { }
所以如果我这样做
Desert.Instance
我将获得 Desert 实例及其所有实现和新方法(以及在基础中定义的方法)。
假设我有 2 个这样的 class:环境和动物。
假设我有 2 个环境的沙漠和丛林。
假设我有蝎子和狮子,它们是 2 种动物。
我想做的是从 Environment 访问 Animal class 的一些属性,但对它的实现一无所知。
非常愚蠢的例子:
- 我将实例化一个沙漠(一次只存在一个环境)
- 沙漠将有一个动物预制件列表,可以实例化以匹配那里允许的物种
- 一旦它被实例化,如果没有那种动物已经存在,自动实例化 1 个(例如蝎子)并且只实例化一个动物,这样我就可以用静态实例 属性 引用它。在实例化的动物被销毁之前,不会实例化其他动物。
第一个问题是,在环境中,我需要一个定义为动物列表的列表(数组、字典、通用列表......等等),然后,沙漠职责来填充它与 Scorpion 和其他人一起列出。显然我不能用通用类型定义结构:
protected List<Animal<T>> animalsList = new List<Animal<T>> ();
另一件事是:看到在空环境中实例化通用动物的动作很常见,我希望我的通用环境可以检查动物是否已经实例化,如果没有,则实例化一个。问题是因为 Animal 是通用的,所以我做不到
if (Animal.Instance == null) {
Instantiate (animalList[Random(0, animalList.Length)]);
}
(请注意,以上为伪代码)
我希望我没有太混乱。也许这是错误的整个想法,也许我不能有泛型,但如果您有任何建议,我们非常欢迎。
谢谢大家 :-)
编辑: 为什么要使用泛型???
因为我试图用通用操作创建一个基础 class 并且因为我需要对 children 实例的静态引用,所以我将基础 classes 定义为通用的。同样,如果我这样做,实例 属性 需要在基础 class 中声明,但如果它被 children 调用,它将返回 children实例.
示例:
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;
}
}
我需要为每个 children 定义实例。可能我很懒,但我认为通用的方式会更好。
这里有很多问题,但首先要了解泛型类型的协变和逆变:
Return an inherited type from a method
这是一个很常见的问题。这是我最近回答的 link。
对于你懒惰的问题,你可以这样做
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>()
}
}
您只需添加代码以在抽象泛型基础中创建实例 class。
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()
.
评论中关于使用工厂的建议 and/or 摆脱单身要求可能是有效的,但您已经非常接近您正在寻找的东西。
编辑:
您也可以像这样访问静态 Instance
属性:
Environment<Desert>.Instance.CommonMethod();
Environment<Desert>.Instance.SandStorm();
但是在指定通用类型之前,您无法获得 Instance
。所以 Environment.Instance
不可用。
为了完整起见,这是我的最终解决方案。请注意,某些部分是伪代码。这只是为了让您了解我的想法。
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。 :-)
我想做的是创建抽象 classes,其中包含要从他们的 children 使用的常用方法。因为我需要 children 的静态实例引用,所以我正在做类似
的事情public abstract class Environment<T> where T : Environment<T> {
private static T s_instance;
public static T Instance {
get {
return (T)s_instance
}
}
}
这样,如果我将在 child 上调用实例 属性,我将获得 child 实例,而不是将 child 声明为的抽象实例:
public Desert : Environment<Desert> { }
所以如果我这样做
Desert.Instance
我将获得 Desert 实例及其所有实现和新方法(以及在基础中定义的方法)。
假设我有 2 个这样的 class:环境和动物。
假设我有 2 个环境的沙漠和丛林。
假设我有蝎子和狮子,它们是 2 种动物。
我想做的是从 Environment 访问 Animal class 的一些属性,但对它的实现一无所知。
非常愚蠢的例子:
- 我将实例化一个沙漠(一次只存在一个环境)
- 沙漠将有一个动物预制件列表,可以实例化以匹配那里允许的物种
- 一旦它被实例化,如果没有那种动物已经存在,自动实例化 1 个(例如蝎子)并且只实例化一个动物,这样我就可以用静态实例 属性 引用它。在实例化的动物被销毁之前,不会实例化其他动物。
第一个问题是,在环境中,我需要一个定义为动物列表的列表(数组、字典、通用列表......等等),然后,沙漠职责来填充它与 Scorpion 和其他人一起列出。显然我不能用通用类型定义结构:
protected List<Animal<T>> animalsList = new List<Animal<T>> ();
另一件事是:看到在空环境中实例化通用动物的动作很常见,我希望我的通用环境可以检查动物是否已经实例化,如果没有,则实例化一个。问题是因为 Animal 是通用的,所以我做不到
if (Animal.Instance == null) {
Instantiate (animalList[Random(0, animalList.Length)]);
}
(请注意,以上为伪代码)
我希望我没有太混乱。也许这是错误的整个想法,也许我不能有泛型,但如果您有任何建议,我们非常欢迎。
谢谢大家 :-)
编辑: 为什么要使用泛型???
因为我试图用通用操作创建一个基础 class 并且因为我需要对 children 实例的静态引用,所以我将基础 classes 定义为通用的。同样,如果我这样做,实例 属性 需要在基础 class 中声明,但如果它被 children 调用,它将返回 children实例.
示例:
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;
}
}
我需要为每个 children 定义实例。可能我很懒,但我认为通用的方式会更好。
这里有很多问题,但首先要了解泛型类型的协变和逆变:
Return an inherited type from a method
这是一个很常见的问题。这是我最近回答的 link。
对于你懒惰的问题,你可以这样做
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>()
}
}
您只需添加代码以在抽象泛型基础中创建实例 class。
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()
.
评论中关于使用工厂的建议 and/or 摆脱单身要求可能是有效的,但您已经非常接近您正在寻找的东西。
编辑:
您也可以像这样访问静态 Instance
属性:
Environment<Desert>.Instance.CommonMethod();
Environment<Desert>.Instance.SandStorm();
但是在指定通用类型之前,您无法获得 Instance
。所以 Environment.Instance
不可用。
为了完整起见,这是我的最终解决方案。请注意,某些部分是伪代码。这只是为了让您了解我的想法。
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。 :-)