2015-02-10 64 views
0

我想要做的是創建包含從子項中使用的常用方法的抽象類。因爲我需要爲孩子們​​一個靜態實例參考,我正在做的東西像創建抽象類,其中包含從子項中使用的常用方法

public abstract class Environment<T> where T : Environment<T> { 

    private static T s_instance; 

    public static T Instance { 
    get { 
     return (T)s_instance 
    } 
    } 
} 

這樣,如果我會叫上孩子的實例屬性,我會得到孩子的實例,而不是抽象的一個聲明子爲:

public Desert : Environment<Desert> { } 

所以,如果我做

Desert.Instance 

我會與所有的實現和新方法的沙漠實例(以及在b中定義的一個ASE)。
假設我有兩個類:環境和動物。
假設我有沙漠和叢林這兩個環境。
比方說,我有蠍子和獅子是2動物。

我想要做的就是從Environment中訪問Animal類的一些屬性,但不瞭解它的實現。

非常愚蠢的例子:

  1. 我將實例化一個沙漠(只是一次一個環境會存在)
  2. 沙漠將有可能被實例化匹配允許種動物組合屋的列表有
  3. 只要它被實例化,如果沒有那種動物已經存在,自動實例化1(例如Scorpion)並且只有一個動物,以便我可以用靜態實例屬性來引用它。在實例化之後,其他動物纔會被實例化。

第一個問題是,在環境,我需要有一個列表(數組,字典,泛型列表...等等)被定義爲動物的名單,那麼,這將是沙漠有義務填補與Scorpion和其他人的名單。顯然,我不能定義與一般類型的結構:

protected List<Animal<T>> animalsList = new List<Animal<T>>(); 


的另一件事是:看,在一個空的環境中實例化一個普通動物的行爲是共同的,我想,我的通用環境可以檢查是否有動物已經被實例化,如果沒有,實例化一個。問題是,因爲動物是通用的,我不能做

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()); 
    } 
} 

在這種情況下,它不允許ŧ o不要

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; 
    } 
} 

我需要定義實例爲每個孩子。可能我很懶,但我認爲通用的方式會更好。

+1

你的第一個問題「顯然我不能定義一個泛型類型的結構」。這是什麼意思?向我們展示不工作的代碼,並解釋爲什麼它不起作用。 – Polyfun 2015-02-10 17:09:24

+0

嗨ShellShock,我編輯了一個例子:問題列表> animalList。對於那個很抱歉。 – Apache81 2015-02-10 17:11:44

+0

當你只是需要多態繼承時,你爲什麼使用單例模式?使用抽象/虛擬方法的多態性將使您能夠在派生對象中調用方法而無需知道其類型,只需知道基本類型即可。 – Polyfun 2015-02-10 17:13:21

回答

1

爲了您lazyness問題,你可以做這樣的事情

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>() 
    } 
} 
+0

這確實是一個非常不錯的選擇!謝謝:-) – Apache81 2015-02-10 18:18:35

+1

'懶惰 Patrick =我自己()' – Patrick 2015-02-10 18:19:23

+0

一定要在某處創建實例和/或在'GetInstance'內檢查'null' – CoderDennis 2015-02-10 18:24:47

0

有很多的問題在這裏,但理解泛型類型協變和逆變啓動:

Return an inherited type from a method

這是一個非常普遍的問題。這是我最近回答的鏈接。

+0

謝謝伊恩。這是非常有用的,但它沒有回答我的問題。 – Apache81 2015-02-11 10:08:57

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()

建議在評論中使用工廠和/或擺脫單身人士的要求可能是有效的,但你已經非常接近你正在尋找的東西。

編輯:

您也可以訪問靜態Instance屬性是這樣的:

Environment<Desert>.Instance.CommonMethod(); 
Environment<Desert>.Instance.SandStorm(); 

但是,直到您指定的泛型類型,你不能讓一個Instance。所以Environment.Instance不可用。

+0

很酷。非常感謝你。之前簽署這個問題作爲我的問題的答案,我會嘗試一下:-P再次感謝你 – Apache81 2015-02-10 18:20:03

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和Coder Dennis。 :-)

相關問題