看,我知道静态类不能继承或实现。问题是“什么是 正确的C#+ OOP模式来实现这个?”。 “这个”描述如下:
我想为一组类定义一个公共的定义和实现集,其中除了一种类型之外的所有类都应该是静态的。也就是说,我想制作一些任意的基本转换器,其中每个转换器具有完全相同的四个成员:
// 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 = 16
和glyphs = { '0', '1', ... 'E', 'F' }
。我相信FromInt
和ToInt
是不言自明的。显然我不需要为base 16实现转换器,但我做需要为行业特定的基础36(0
- Z
的字形实现一个Code 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) { }
}
我可以看到为什么这对编译器不起作用 - 静态方法没有vtable,所有这些。我理解在C#中,静态类不能实现接口或继承任何东西(除了object)(参见Why Doesn't C# Allow Static Methods to Implement an Interface?,Why can't I inherit static classes?)。
那么是什么“正确”的C#+ OOP模式来实现这个呢?
答案 0 :(得分: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);
}
}
答案 1 :(得分:2)
你要进入的方向......不是一个好主意。
我建议你模仿System.Text.Encoding提供的模式。
它具有Encoding类型的公共静态属性,它是不同类型文本编码的Encoding类的标准实现。
在您的情况下,您将提供抽象基类而不是接口,并将您的常见实现公开为静态属性。
然后,开发人员可以轻松访问您提供的常用转换器的实现,或者他们可以实现自己的实现。
答案 2 :(得分:1)
为什么要让它静止?
Singleton似乎就是你要找的东西。
答案 3 :(得分:1)
答案是Singleton模式。请参阅示例Implementing Singleton in C#。
Luiggi Mendoza提供了这个答案,我将其标记为答案,但后来由于某种原因将其删除。我正在重新发布它。