I'm trying to implement a class to access items of different types, in a similar way to database rows.
However, I have two different ideas in mind, and I don't know which one to choose:
Design 1
public enum ObjectTypeA
{
Undefined,
Integer,
Float
}
public class MyObjectA
{
private object val;
public ObjectTypeA Type
{
get;
private set;
}
public int Integer
{
get
{
if (Type != ObjectTypeA.Integer) throw new Exception();
return (int)val;
}
set
{
Type = ObjectTypeA.Integer;
val = value;
}
}
public float Float
{
get
{
if (Type != ObjectTypeA.Float) throw new Exception();
return (float)val;
}
set
{
Type = ObjectTypeA.Float;
val = value;
}
}
}
- Less compile-time checks possible.
- Can't use the is operator, GetType(), etc. (reinvents the type system).
- Boxing and unboxing for value types.
- Can be inherited by other classes (e.g. I can create a "named object" using inheritance).
Design 2
public abstract class MyObjectB
{
}
public class MyIntegerB : MyObjectB
{
public int Value
{
get;
set;
}
public MyIntegerB(int _value)
{
Value = _value;
}
}
public class MyFloatB : MyObjectB
{
public float Value
{
get;
set;
}
public MyFloatB(float _value)
{
Value = _value;
}
}
- Shorter and simpler implementation.
- Very verbose (casting) to use.
Performance is not critical, but it's still important, since most of the objects that are going to be stored are integers or floats, so boxing overhead matters.
The classes will just contain the values, not methods that depend on the type, etc. so it doesn't matter if the solution uses inheritance.
IMPORTANT: One of the requirements is that there may be two types that use the same underlying type (e.g. two classes derived from MyObjectB may use int as the Value), so using object or generics may not be possible.
Any suggestion about which design to use, or another different design?
EDIT: The reason I don't like the second one is because it's very verbose to use:
MyObjectB objB = new MyIntegerB(12);
Console.WriteLine(((MyIntegerB)objB).Value);
And because I can't inherit it to create something like a "named object", so I have to attach MyObjectB to the class, and the usage is even more verbose.