I have a class:
class abc <T> {
private T foo;
public string a {
set {
foo = T.parse(value);
}
get{
return foo.toString();
}
}
}
However the T.parse command is giving me an error. Anyone of a way to do what I am trying to do?
I am using this as a base class for some other derived classes.
Edit:
What I ended us doing:
Delegate parse = Delegate.CreateDelegate(typeof(Func<String, T>), typeof(T).GetMethod("Parse", new[] { typeof(string) }));
I do that once in the constructor
and then I do the following in my property:
lock (lockVariable)
{
m_result = (T)parse.DynamicInvoke(value);
dirty = true;
}
C# generic types are not C++ templates. A template lets you do a fancy “search and replace” where you would substitute the name of a type that implements a static parse method for T. C# generics are not a textual search-and-replace mechanism like that. Rather, they describe parameterized polymorphism on types. With a template, all that is required is that the specific arguments you substitute for the parameters are all good. With a generic every possible substitution whether you actually do it or not, has got to be good.
UPDATE:
A commenter asks:
Now we come to the deep question underlying the original question.
To clarify for the reader unfamiliar with Haskell: Since C# 2.0, C# has supported “generic” types, which are a “higher” kind of type than regular types. You can say
List<int>and a new type is made for you that follows theList<T>pattern, but it is a list specifically of integers.Haskell supports an even higher kind of type in its type system. With generic types you can say “every
MyCollection<T>has a methodGetValuethat takes an int and returns aT, for anyTyou care to name”. With generic types you can put constraints on T and say “and furthermore, T is guaranteed to implementIComparable<T>…” With Haskell typeclasses you can go even further and say the moral equivalent of “…and moreover, T is guaranteed to have a static methodParsethat takes a string and returns a T”.The “Read” typeclass is specifically that typeclass that declares the moral equivalent of “a class C that obeys the Read typeclass pattern is one that has a method Parse that takes a string and returns a C”.
C# does not support that kind of higher type. If it did then we could typecheck patterns in the language itself such as monads, which today can only be typechecked by baking them into the compiler (in the form of query comprehensions, for example.) (See Why there is no something like IMonad<T> in upcoming .NET 4.0 for some more thoughts.)
Since there is no way to represent that idea in the type system, you’re pretty much stuck with not using generics to solve this problem. The type system simply doesn’t support that level of genericity.
People sometimes do horrid things like:
but that is in my opinion a bit abusive; it really is not generic.