Let\'s say I have an object that represents a field of data, that object needs the following properties: Name, Type, Value, Length. Here is the object:
class
I suggest you to define an interface and Field<T>
implements that interface
public interface IField
{
}
public class Field<T> : IField
{
public string Name { get; set; }
public Type Type
{
get
{
return typeof(T);
}
}
public int Length { get; set; }
public T Value { get; set; }
}
so you can write this code:
var list = new List<IField>();
now this list can contain any object of type Field<T>
Yes, generics is a good choice. The key to achieving type-safety (and being identify the type with the Type
property is to add an abstraction between the list and Field<T>
class.
Have Field<T>
implement the interface IField
. This interface doesn't need any members.
Then declare your list as being List<IField>
.
That way you constrain the list to only contain fields, but each field can be of a different type.
To then read the values later, just do
foreach(var field in list)
{
var type = field.Type;
....
}
As a few commenters already mentioned, you cannot access the Type
property if you create an empty Interface, so I would rather do:
public interface IField
{
Type Type { get; }
string Name { get; set; }
int Length { get; set; }
}
public class Field<T> : IField
{
public string Name { get; set; }
Type IField.Type => typeof(T);
public int Length { get; set; }
public T Value { get; set; }
public override string ToString()
{
return Value.ToString();
}
}
Then you can check of which datatype the value property is and cast the object to the right type:
class Program
{
static void Main(string[] args)
{
var fieldList = new List<IField>()
{
new Field<string>()
{
Value = "Hello World!",
Length = 12,
Name = "A string"
},
new Field<int>()
{
Value = 4711,
Length = sizeof(int),
Name = "An integer value"
},
new Field<double>()
{
Value = 2.4,
Length = sizeof(double),
Name = "A double value"
},
};
foreach (var field in fieldList)
{
if (field.Type == typeof(string))
{
PrintField(field, "String value:");
}
else if (field.Type == typeof(int))
{
PrintField(field, "Integer value:");
}
else if (field.Type == typeof(double))
{
PrintField(field, "Double value:");
}
}
}
static void PrintField(IField field, string info)
{
Debug.WriteLine(info);
Debug.WriteLine($"\tName: {field.Name}, Length: {field.Length}, Value: {field}");
}
}
The code produces the following output:
// String value:
// Name: A string, Length: 12, Value: Hello World!
// Integer value:
// Name: An integer value, Length: 4, Value: 4711
// Double value:
// Name: A double value, Length: 8, Value: 2,4