I want to create a generic class where the type of the class can Parse strings.
I want to use this class for any class that has a static function Parse(string), like System.Int32, System.Double, but also for classes like System.Guid. They all have a static Parse function
So my class needs a where clause that constraints my generic type to types with a Parse function
I'd like to use it like this:
class MyGenericClass<T> : where T : ??? what to do ???
{
private List<T> addedItems = new List<T>()
public void Add(T item)
{
this.AddedItems.Add(item);
}
public void Add(string itemAsTxt)
{
T item = T.Parse(itemAsTxt);
this.Add(item);
}
}
What to write in the where clause?
I was not happy with the answers that would use reflection to do the Parsing.
I prefer a solution that is type safe, so the compiler would complain about the a missing Parse function.
Normally you would constraint to a class that has an interface. But as others said, there is no common interface. Come to think of it I don't need an interface, I need a function that I can call
So my solution would be to insist that creators would provide a delegate to the Parse Function that would parse a string to type T
class MyGenericClass<T>
{
public MyGenericClass(Func<string, T> parseFunc)
{
this.parseFunc = parseFunc;
}
private readonly Func<string, T> parseFunc;
public void Add(string txt)
{
this.Add(parseFunc(txt));
}
}
Usage:
MyGenericClass<Guid> x = new MyGenericClass<Guid>(txt => Guid.Parse(txt));
MyGenericClass<int> y = new MyGenericClass<int> (txt => System.Int32.Parse(txt));
The answer is simpler than I thought
I might be misunderstanding your question, but will this do the trick?
static void Main(string[] args)
{
Guid g = DoParse<Guid>("33531071-c52b-48f5-b0e4-ea3c554b8d23");
}
public static T DoParse<T>(string value)
{
T result = default(T);
MethodInfo methodInfo = typeof(T).GetMethod("Parse");
if (methodInfo != null)
{
ParameterInfo[] parameters = methodInfo.GetParameters();
object classInstance = Activator.CreateInstance(typeof(T), null);
object[] parametersArray = new object[] { value };
result = (T)methodInfo.Invoke(methodInfo, parametersArray);
}
return result;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With