2012-02-15 52 views
3

看,我知道静态类不能继承或实现。问题是“什么是正确的C#+ OOP模式来实现这个?”。 “This”描述如下:如何在静态类中使用多态或继承?

我想为一组类定义和实现的通用集合,其中除一个类型之外的所有类型都应该是静态的。也就是说,我要做出一些武断基地转换器,其中每个具有完全相同的四个成员:

// Theoritical; static classes can't actually implement 
interface IBaseConverter { 
    int Base { get; } 
    char[] Glyphs { get; } 
    int ToInt(string value); 
    string FromInt(int value); 
} 

// AND/OR (interface may be superfluous) 
public class BaseConverter : IBaseConverter{ 
    public BaseConverter(int Base, char[] Glyphs) { 
     this.Base = Base; 
     this.Glyphs = Glyphs; 
    } 
    public int Base { get; private set; } 
    public char[] Glyphs { get; private set;} 
    public int ToInt(string value) { // shared logic... 
    public string FromInt(int value) { // shared logic... 
} 

他们还可以共享基础上的Base价值和字形的有序集合完全相同的实现逻辑。例如Base16Converter可能有Base = 16glyphs = { '0', '1', ... 'E', 'F' }。我相信FromIntToInt是不言自明的。显然,我不需要实现基于16的转换器,但是我需要为特定于行业的基础36(0 - ZCode 39的字形)实现一个转换器。与内置的转换和字符串格式化功能(如[Convert]::ToInt32("123",16))一样,这些都是强调静态方法 - ,当基础和字形预先确定时

我想保持可与任意的字形和底座,如被初始化实例的版本:

BaseConverter converter = new BaseConverter(7, new[]{ 'P', '!', 'U', '~', 'á', '9', ',' }) 
int anumber = converter.ToInt("~~!,U") // Equals 8325 

但我也希望有一个静态类的Base36Code39Converter。把这个的另一种方式是,任何static实施者只是硬编码的基础和字形:

// Theoritical; static classes can't inherit 
public static class Base36Code39Converter : BaseConverter { 
    private static char[] _glyphs = { '0', '1', ... 'Z' }; 
    static Base36Code39Converter : base(36, _glyphs) { } 
} 

我明白为什么这不会对编译器的工作 - 没有虚函数表的静态方法和所有。我知道在C#中,静态类不能实现接口或从任何东西(除了对象)继承(请参见Why Doesn't C# Allow Static Methods to Implement an Interface?,Why can't I inherit static classes?)。

那么到底什么是的“右”C#+ OOP模式来实现这个?

+0

这不是[单件模式](http://www.dofactory.com/Patterns/PatternSingleton.aspx)的工作吗?另外,这里有一篇关于[Singleton VS Static Class](http://www.dotnetperls.com/singleton-static)的好文章。 – 2012-02-15 14:46:36

回答

1

答案是Singleton模式。例如参见Implementing Singleton in C#

Luiggi门多萨提供了这个答案,我标记为答案,但后来因为某种原因删除了它。我为了完整而重新发布它。

+0

感谢您在此提供完整性。 – RvdV79 2017-04-26 09:32:26

1

为什么你想让它变成静态的?

Singleton似乎是你在找什么。

+1

尽管_singleton设计pattern_是我正在寻找的模式(正如Luiggi所指出的),但您链接到维基百科消歧页面更多地显示了这个术语为什么会令人困惑:它也意味着一组一个,它也在.NET中实现4.0+作为Tuple 。 MDSN本身同时具有描述[** singleton design pattern **](http://msdn.microsoft.com/zh-cn/library/ff650316.aspx)的文档,并描述了[** Tuple class **]( http://msdn.microsoft.com/en-us/library/dd386941.aspx)为“1元组或** singleton **”。“ – 2012-02-15 15:58:33

+0

我应该看看我链接到更好:) – penartur 2012-02-15 17:51:44

2

你总是可以使用组合。在这种情况下,您的静态类将有相应的转换器的一个实例,只是代理,任何来电:

public static class Base36Code39Converter 
{ 
    private static BaseConverter _conv = 
     new BaseConverter(36, new[]{ '0', '1', ... 'Z' }); 

    public static int ToInt(string val) 
    { 
     return _conv.ToInt(val); 
    } 
} 
2

你要去的方向......与其说是一个好主意。

我建议你模仿System.Text.Encoding提供的模式。

它具有Encoding类型的公共静态属性,它们是用于不同类型的文本编码的Encoding类的标准实现。

  • ASCII
    • 获取的ASCII(7位)字符集编码。
  • BigEndianUnicode
    • 获取使用大端排序的字节顺序的UTF-16格式编码。
  • 默认
    • 获取操作系统的当前ANSI代码页的编码。
  • 的Unicode
    • 获取用于使用所述小端排序的字节顺序的UTF-16格式编码。
  • UTF32
    • 获取用于使用所述小端排序的字节顺序的UTF32格式的编码。
  • UTF7
    • 获取的UTF7格式的编码。
  • UTF8
    • 获取的UTF8格式的编码。

在你的情况,你会提供一个抽象基类,而不是一个接口,并揭露共同实现的静态属性。

开发人员可以轻松访问您提供的通用转换器的实现,或者他们可以实现自己的实现。

+0

+1 - 虽然Luiggi提供了一个明确的理论解释的链接的直接答案,这是BCL中使用的模式的一个很好的例子。 – 2012-02-15 14:58:48

+0

@jmh_gr:呃,它并不是真的是一样的,但是无论如何,你会明白这一点,在这种情况下,它总是很好地看待类似模式的框架,因为它们经过深思熟虑并且对所有人都熟悉使用BCL的开发人员。 – Will 2012-02-15 15:00:24