How to use polymorphism or inheritance in static classes? - c#

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?

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.

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);
}
}

Why do you want to make it static?
Singleton seems to be what you're looking for.

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.

Related

Use Span<T> as C# class level variable

I'm writing a high-performance parser for a comma delimited stream (network). My goal is to parse and convert directly from binary to dotnet primitives. Based on my testing thus far, Span performance is incredible, but the type is difficult to work with due to restrictions inherent to ref structs. I've hit a roadblock trying to find an efficient way to store Span constants (comma, newline, etc.) used throughout my application. The only solution that seems to exist to store them as byte and convert them in the class bodies of methods...or hardcode Span<byte> delimiter = Encoding.UTF8.GetBytes("\r\n") in every method body.
The following is what I'd like to achieve but it gives the error - `CS8345 Field or auto-implemented property cannot be of type 'Span' unless it is an instance member of a ref struct.
public class Parser
{
Span<byte> NewLine = new byte[]{ (byte)'\n' };
}
There's got to be a better way! Please help!
You're running into issues because ref structs, like Span<T>, are special data types with restrictions that ensure they cannot escape the stack. Classes are reference types that live on the heap. As such, if Span were a member of a class it would break the "stack only" rule. However, static properties that are with implemented (not auto implements e.g. { get; set;} are allowed and seem to be the solution you're look for. See the following example...
public class Parser
{
static Span<byte> NewLine => { (byte)'\n' };
static ReadOnlySpan<byte> Comma => { (byte)',' };
private static Span<byte> TraditionSyntax
{
get
{
return new[] {(byte)'\n' };
}
}
}
Note, the "string"u8.Array() syntax is a literal that converts the string directly into into UTF8 as if you called the encoder the way your referenced in your example. That said, make sure to test the literal to ensure it produces what you expect. It's not always consistent with Encoding.UTF8.
Don't get thrown off by method body (property getter).
There's a compiler optimization that avoids an allocation when you use (byte)
You can create ReadOnlySpan<byte> with UTF-8 literal in .NET 7:
class Consts
{
public static ReadOnlySpan<byte> Delim => "\n"u8;
}
Or use Memory/ReadOnlyMemory:
public class Consts
{
public static ReadOnlyMemory<int> Type { get; } = new []{1};
}
And usage:
ReadOnlySpan<int> span = Consts.Type.Span;
Or decorate aforementioned approach into method/expression bodied property:
class Consts
{
private static readonly byte[] _delim = { (byte)'\n' };
public static ReadOnlySpan<byte> Delim => _delim;
}
Demo

Simulate deriving from a value type

I am building a calculator, and I would like to have a type called ButtonDigit, which may contain chars 0 to 9, and I would like to call it ButtonDigit'. Ideally it would be derived fromchar`, but that isn't allowed, and I don't want an object like:
public class ButtonChar
{
public char Value { get; set; }
}
I find that rather clumsy having to always instantiate a ButtonChar object and access the Value property when I want the character stored. What would be ideal is a type of alias for the char set 0-9, but we don't get that. Am I stuck with a ButtonChar object, or a plain char and always checking it's in the range?
Use a generic class to handle different types
public class Button<T>
{
public T {get;set;}
}
You can add a generic validation system on the setter - for example by keeping a list of Func that would be applied to any input, eg:
var validations = new List<Func<T, bool>>();
if (validations.Any(validation => !validation(tValue))) {
throw new InvalidValueException(tValue);
}
// in the char example
validations.Add(myChar => myChar <= '9' && myChar >= '0');
Char is a struct, so you can't inherit it. I would say the custom ButtonChar class is a decent approach though.
Another approach is to just create a bunch of char constants
public static class MyConstants
{
public static char Zero{get{return '0';}}
....
}
The range comparison will be easy since it's a sequential range 0-9

Exposing common values from a custom structure/type

One of my projects has a value type/struct that represents a custom identifier string for a video format. In this case, it's going to contain a content type string, but that can vary.
I've used a struct so it can be strongly type when it's passed around, and perform some sanity checks on the initial string value.
public struct VideoFormat {
private string contentType;
public VideoFormat(string contentType) {
this.contentType = contentType;
}
public string ContentType {
get { return this.contentType; }
}
public override string ToString() {
return this.contentType;
}
// various static methods for implicit conversion to/from strings, and comparisons
}
As there are a few very common formats, I've exposed these as static read only fields with default values.
public static readonly VideoFormat Unknown = new VideoFormat(string.Empty);
public static readonly VideoFormat JPEG = new VideoFormat("image/jpeg");
public static readonly VideoFormat H264 = new VideoFormat("video/h264");
Is it better to expose the common values as static read only fields or as get only properties? what if I want to change them later? I see both methods used throughout the .Net framework, e.g. System.Drawing.Color uses static readonly properties while System.String has a static read only field for String.Empty, and System.Int32 has a const for MinValue.
(Mostly copied from this question but with a more specific and not directly related question.)
Properties are a good idea unless you are declaring something that never changes.
With properties you can change the inside implementation without affecting programs consuming your library and handle changes / variations. Consuming programs wont break and wont require to be recompiled.
e.g. (I know this is a bad example but you get the idea..)
public static VideoFormat H264Format
{
get{
// This if statement can be added in the future without breaking other programs.
if(SupportsNewerFormat)
return VideoFormat.H265;
return VideoFormat.H264;
}
}
Also keep in mind that if you decided to change a field to a property in the future, consuming code breaks.

Generating an identifier for objects so that they can be added to a hashtable I have created

I have a hashtable base class and I am creating different type of hashtable by deriving from it. I only allow it to accept objects that implement my IHashable interface.For example -
class LinearProbingHashTable<T> : HashTableBase<T> where T: IHashable
{
...
...
...
}
interface IHashable
{
/**
* Every IHashable implementation should provide an indentfying value for use in generating a hash key.
*/
int getIdentifier();
}
class Car : IHashable
{
public String Make { get; set; }
public String Model { get; set; }
public String Color { get; set; }
public int Year { get; set; }
public int getIdentifier()
{
/// ???
}
}
Can anyone suggest a good method for generating an identifier for the car that can be used by the hash function to place it in the hash table?
I am actually really looking for a general purpose solution to generating an id for any given class. I would like to have a base class for all classes, HashableObject, that implements IHashable and its getIdentifier method. So then I could just derive from HashableObject which would automatically provide an identifier for any instances. Which means I wouldn't have to write a different getIdentifier method for every object I add to the hashtable.
public class HashableObject : IHashable
{
public int getIdentifier()
{
// Looking for code here that would generate an id for any object...
}
}
public class Dog : HashableObject
{
// Dont need to implement getIdentifier because the parent class does it for me
}
I would split the problem in two:
How to generate hash codes of primitive types: strings, integers etc.
How to combine multiple hash codes into one hash code
using (1) and then (2) you can generate the hash code of any class or structure.
The naive way to do (1) for strings is to add the code of all characters in the string:
public static int getStringIdentifier(string str)
{
int result = 0;
foreach (char c in str) {
result += (int)c;
}
return result;
}
Similar naive algorithms can be used for other basic data types (that are all array of bytes in the end..).
The naive way to do (2) is to simply combine the various hash codes with XOR:
public int getIdentifier()
{
return getStringIdentifier(Make) ^ getStringIdentifier(Model) ^ getStringIdentifier(Color);
}
These algorithms will work, but won't generate good distributions of the hash code values - i.e. there will be collisions.
If you want better algorithms you can have a look at how the .NET framework does it - here is the source code of the class used intenally to combine multiple hash codes, and here is the source code of the String class - including String.GetHashCode().
As you can see they are variants of the naive one above, with different starting values and more complex combinations.
If you want a single method that works on different classes the way to do it is to use reflection to detect all the primitive fields contained in the class, compute their hash code using the primitive functions and then combine them.
It is tricky and extermely .NET-specific though - my preference would be to create methods handling the primitive types and then just re-define getIdentifier() for each class.
You should use the default GetHashCode method. It does everything you need. Documentation. It exists for all objects and is virtual so you can choose to override it if you wish.
I assume you know how to generate hashes for the primitive data types (ints, floats, strings, non-extended object, and a few others) and combine multiple hashes, so I won't bore you with the details.
If you absolutely must write your own generic hash function you could use Reflection. You would recursively hash each data member until you got to a primitive type where you'd have to manually handle those cases. There will likely be problems with certain data-types that have unmanaged data. In particular, one example would be a .net class that has a pointer to a class with an unspecified data-structure. Reflection clearly can't handle this case and would not be able to hash the unmanaged portion of the class.

How to name a class that wraps several primitive types?

I have a naming problem for some of my classes. I need to wrap some primitive .net types into a class like the following. There will be about 20 of such classes.
(The naming is crap, of course. Just for a demonstrative purpose)
public class Int32Single
{
public int Value { get; set; }
}
public class Int32Double
{
public int Value1 { get; set; }
public int Value2 { get; set; }
}
public class DoubleSingle
{
public double Value { get; set; }
}
I can't use a generic approach for this.
How should I name such wrapper classes, where each class name should provide the necessary information which primite types are wrapped and in which quantity?
It might also be possible that I have class that contains mixed primite types.
This doesn't seem like a very good idea at all. You have both the Tuple class and a standard array available, that both make more sense in any conceivable use case. However, that doesn't answer your question, so...
The most intuitive name for a wrapper class would follow the convention of {type-name}Wrapper, or for example, Int32Wrapper. In your case, the wrapped object is a primitive type, so makes sense to call the class a "Tuple". Since you want to specify the size of the Tuple in your class name, {primitive-type-name}{size}Tuple seems like the most intuitive naming convention but this causes several problems.
The natural language used to describe Tuples create ambiguity (such as Single and Double because they conflict with the Type names). (e.g. DoubleDouble is bad)
Integers are used in the naming of some primitive types so this could cause ambiguity. (e.g. Int322Tuple is bad).
We can't move the size to the beginning such as 2Int32Tuple because integers are not valid characters to begin a class name. So, There are two approaches that I think could work.
I think your best bet to get around these constraints, is to use a {primitive-type-name}{text-represented-size}Tuple convention. (e.g. Int32TwoTuple or DoubleTwoTuple). This convention expresses the contents of the wrapper class without ambiguity, so it seems like a good approach. In addition the name begins with the primitive type name, so, if you have a lot of these classes, it will be easier for your IntelliSense to fill in the correct class name, and it will alphabetically be listed next to the primitive type that is being wrapped.
Generics can help you out here:
public class WrapTwo<T>
{
public T Value1 { get; set; }
public T Value2 { get; set; }
}
public class WrapOne<T>
{
public T Value1 { get; set; }
}
And have you considered the Tuple class?
OneInt32, TwoInt32s, TwoDoubles? Doesn't sound great.
Tuples? http://www.dotnetperls.com/tuple
I don't very fond of Tuples or arrays, because both don't tell much about their purpose. Well, I use them. But mostly as internal members of classes, local variables, or with 3rd party/legacy code.
Back to naming. Compare:
Tuple<int,int> a = Tuple.Create(10,10);
Int32Double b = new Int32Double(15, 15);
WrapTwo<int> c = new WrapTwo<int>(20, 20);
With
Point a = new Point(10, 10);
Vertex b = new Vertex(15, 15);
One can argue, that 'a' is not good name for variable (and suggest to use 'pointA' instead). But I think it's pretty good in context of geometry application.
Not just type name and creation code looks obscure, but consider type fields names:
a.X = 20;
b.Value1 = 20;
So, I think you need some self-descriptive type in context of your application domain.

Categories