3

Look, I know static classes can't inherit or implement. The question is "what the heck is the right C# + OOP pattern to implement this?". "This" is described below:

I want to define a common set of both definition and implementation for a group of classes where all but one type should be static. Namely, I want to make some arbitrary base converters where each have exactly the same four members:

// 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...
}

They can also share the exact same implementation logic based on the value of Base and the ordered collection of glyphs. For example a Base16Converter would have Base = 16 and glyphs = { '0', '1', ... 'E', 'F' }. I trust the FromInt and ToInt are self-explanatory. Obviously I wouldn't need to implement a converter for base 16, but I do need to implement one for an industry-specific base 36 (the 0 - Z glyphs of Code 39). As with the built-in conversion and string formatting functions such as [Convert]::ToInt32("123",16) these are emphatically static methods -- when the base and glyphs are pre-determined.

I want to keep an instance version that can be initialized with arbitrary glyphs and base, such as:

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

But I also want a static class for the Base36Code39Converter. Another way of putting this is that any static implementers just have hard-coded base and glyphs:

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

I can see why this wouldn't work for the compiler -- there is no vtable for static methods and all that. I understand that in C# a static class cannot implement interfaces or inherit from anything (other than object) (see Why Doesn't C# Allow Static Methods to Implement an Interface?, Why can't I inherit static classes?).

So what the heck is the "right" C# + OOP pattern to implement this?

Community
  • 1
  • 1
Joshua Honig
  • 12,925
  • 8
  • 53
  • 75
  • Isn't this a work for [singleton pattern](http://www.dofactory.com/Patterns/PatternSingleton.aspx)? Plus, here is a nice article about [Singleton VS Static Class](http://www.dotnetperls.com/singleton-static). – Luiggi Mendoza Feb 15 '12 at 14:46

4 Answers4

3

The direction you're going in... Not so much a good idea.

I would suggest you emulate the pattern presented by the System.Text.Encoding.

It has public static properties of type Encoding which are standard implementations of the Encoding class for different types of text encoding.

  • ASCII
    • Gets an encoding for the ASCII (7-bit) character set.
  • BigEndianUnicode
    • Gets an encoding for the UTF-16 format that uses the big endian byte order.
  • Default
    • Gets an encoding for the operating system's current ANSI code page.
  • Unicode
    • Gets an encoding for the UTF-16 format using the little endian byte order.
  • UTF32
    • Gets an encoding for the UTF-32 format using the little endian byte order.
  • UTF7
    • Gets an encoding for the UTF-7 format.
  • UTF8
    • Gets an encoding for the UTF-8 format.

In your case, you would provide an abstract base class, rather than an interface, and expose your common implementations as static properties.

Developers would then have easy access to implementations for the common converters you provide, or they would be able to implement their own.

  • +1 - Though Luiggi provided the direct answer with a link to a clear theoreticaly explanation, this is a great example of the pattern in use in the BCL. – Joshua Honig Feb 15 '12 at 14:58
  • @jmh_gr: Well, its not *really* the same. But you get the idea, anyhow. In situations like this, its always good to look at the framework for similar patterns, as they are reasonably well thought out and are familiar to all developers who use the BCL. –  Feb 15 '12 at 15:00
2

You could always use composition. In this case, your static class would have an instance of the appropriate converter and just proxy any calls to that:

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);
    }
}
Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
1

Why do you want to make it static?

Singleton seems to be what you're looking for.

penartur
  • 9,792
  • 5
  • 39
  • 50
  • 1
    Although the _singleton design pattern_ is the pattern I was looking for (as noted by Luiggi), your link to the Wikipedia disambiguation page more shows why this term is confusing: it also means a set of one, which is also implemented in .NET 4.0+ as a Tuple. MDSN itself has both documention describing the [**singleton design pattern**](http://msdn.microsoft.com/en-us/library/ff650316.aspx) AND describes the [**Tuple class**](http://msdn.microsoft.com/en-us/library/dd386941.aspx) as "a 1-tuple, or **singleton**." – Joshua Honig Feb 15 '12 at 15:58
  • I should have look at what i'm linking to better :) – penartur Feb 15 '12 at 17:51
1

The answer was the Singleton pattern. See for example Implementing Singleton in C#.

Luiggi Mendoza provided this answer, which I marked as an answer, but then he deleted it for some reason. I'm reposting it for completeness.

Joshua Honig
  • 12,925
  • 8
  • 53
  • 75