Having the following generic class that would contain either string, int, float, long
as the type:
public class MyData
You can't do it the way you want.
When an instance of a generic class is initialized, it is bound to particular type. Since you want to hold objects of different types in your list, you have to create an instance bound to the least common denominator — in your case it's Object.
However, that means that Data property now will return an object of type Object. The compiler cannot infer the actual data type at compile time, so it can choose the appropriate SomeMethod
overload.
You have to either provide an overload of SomeMethod
that takes Object as a parameter, or remove the requirement to hold different such different types in your collection.
Or you can go with a standard IEnumerable
collection (like Array) and use the OfType<>
extension method to get the subset of the collection of particular type.
Just use an ArrayList and forget the MyData<T>
type.
ArrayList myStuff = getStuff();
float x = myStuff.OfType<float>().First();
SomeMethod(x);
string s = myStuff.OfType<string>().First();
SomeMethod(s);
The problem with MyData<T>
is that you're expecting the compiler to check a type that is only known at runtime. Compilers check types that are known at compile time.
You can create a generic wrapper for SomeMethod
and check for the type of the generic argument, then delegate to the appropriate method.
public void SomeMethod<T>(T value)
{
Type type = typeof(T);
if (type == typeof(int))
{
SomeMethod((int) (object) value); // sadly we must box it...
}
else if (type == typeof(float))
{
SomeMethod((float) (object) value);
}
else if (type == typeof(string))
{
SomeMethod((string) (object) value);
}
else
{
throw new NotSupportedException(
"SomeMethod is not supported for objects of type " + type);
}
}