2012-02-27 74 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