2012-02-27 79 views
4

我有一個系統在大量的Things上執行操作,這些可以被認爲是通過通信通道訪問的硬件設備。C#,抽象超類實現由子類定義的具體變量?

我使用一個管理器構造來接受單個Things的任務。現在,至少有三種類型的Thing,它們與它們具有稍微不同的屬性。經理必須知道這些額外的屬性,因爲他們需要正確地執行任何操作(一些Things必須有他們的X foo'd而不是他們的Y等)。

目前我有每種類型的東西單獨的經理類。這導致大量的重複,因爲Things大部分是相似的。

如果我可以有一個抽象管理器來實現大量的功能,然後每個具體的實現可以提供少量的額外位,那就太好了。

這裏是一個大大簡化例如:

public abstract class ThingManager 
{ 
    private ConcurrentDictionary<Guid, ??ThingTask??> _ThingTaskQueue; 

    public virtual AddNewThingTask(<params>) 
    { 
     ??ThingTask?? NewTask = new ??ThingTask??(<params>); 
     _ThingTaskQueue.Add(NewTask); 
     Monitor.Pulse(_NewDataToProcess); 
    } 

    /* Implemented by the concrete, will depend on the type of ??ThingTask?? */ 
    public abstract GetSomeTaskParameterForAThing(Guid thingID) 
} 

public class ThingTask 
{ 
    public enum ThingOperation 
    { 
     Foo, 
     Bar 
    }; 

    public String Name { get; set; }; 
    public ThingType Type { get; set; }; 
    public ThingOperation Operation { get; set; } 
} 

public class AdvancedThingTask 
{ 
    public enum ThingOperation 
    { 
     Foo, 
     Bar, 
     Baz 
    }; 

    public String Name { get; set; }; 
    public ThingType Type { get; set; }; 
    public ThingOperation Operation { get; set; } 
    public Boolean EnableFrobber { get; set; } 
} 

正如你可以看到我需要一些方法,確定具體ThingManager時有??ThingTask??是A ThingTaskAdvancedThingTask。然後,在實現抽象方法時,要使用額外的屬性。

使用接口??ThingTask??將無法​​正常工作,因爲必須在接口中聲明屬性,並且每個屬性都有不同的可用屬性。

我得到我想的東西就如何做到這一點乾淨很明顯的感覺,希望有人能幫助:)

回答

3

使用泛型,而不是一個純粹的抽象類,成才線沿線的:

public abstract class ThingManager<T> where T : ThingTask 

依賴於你的全面實施,我懷疑這是否會需要保持抽象

+0

非常感謝您的評論。我只是谷歌泛型類,這看起來像強大的東西。我會立即閱讀。 – Cursorkeys 2012-02-27 17:28:32

+0

它們在C#中被稱爲泛型,並且與C++模板不同 – 2012-02-27 17:48:03

+0

哦哇,泛型非常好。我已經實現了整個事情,並使用[link](http://stackoverflow.com/a/3054835/1228201)中顯示的Reflection方法從我的泛型類型參數中提取合適的構造函數。這是一個恥辱它現在工作,這是非常有趣:) – Cursorkeys 2012-02-28 09:30:07

0

是否有任何理由你不AdvancedThingTask ThingTask的子類?

public class ThingTask 
{ 
    public virtual string Name { get; set; } 
    public virtual ThingType Type { get; set; } 
    public virtual ThingOperation Operation { get; set; } 

    public virtual void DoThing() { /*Do something associated with ThingTask*/ } 
} 

public class AdvancedThingTask : ThingTask 
{ 
    public bool EnableFrobber { get; set; } 

    public override void DoThing() { /*Do something associated with AdvancedThingTask*/ } 
} 

我這個看到的唯一問題是,ThingOperation將需要聲明的類之外,使其可以擁有所有的值,或一些其他的解決方案,使類具有不值在基地宣言。這個問題可以通過將你想做的虛擬方法放在類中來解決。

P.S.爲什麼你的房產以下劃線開頭?通常這是爲私有變量保留的。

+0

是的,ThingOperation枚舉將在Task類之間不同,所以我不認爲子類化是最好的方法。下劃線是匿名留下的,它們是獨立的私人變量,具有獨立的公共設置者和獲取者。 – Cursorkeys 2012-02-27 17:36:07

+0

@Cursorkeys你可以使'ThingOperation Operation'不是虛擬的,並將它從基類中移除,甚至可以將其設置爲私有的,以便它只能用於DoThing()或類似的 – 2012-02-27 17:43:55