Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic class where type can Parse strings

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?

like image 973
Harald Coppoolse Avatar asked Feb 02 '18 11:02

Harald Coppoolse


2 Answers

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

like image 116
Harald Coppoolse Avatar answered Oct 22 '22 06:10

Harald Coppoolse


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;
    }
like image 32
WynDiesel Avatar answered Oct 22 '22 06:10

WynDiesel