Reputation: 401
Is there a way in C# to perform a user defined conversion for generic types ?
for example:
class Stack<T>
{
private T x; //should be an array but doesn't matter for this example
public Stack(T input)
{
x = input;
}
public Stack<Q> Convert<Q>(Stack<T> inputStack)
{
//what would go here ? The call is below.
}
}
//main code
Stack<int> stack = new Stack<int>(2);
Stack<long> longstack = stack.Convert<long>(stack);
I would imagine that the compiler can deduce that Q is long and T is int in the Convert function, but it doesn't seem to work.
Upvotes: 3
Views: 323
Reputation: 1819
Here is extension method for standart Stack class (you can rewrite it a little and use like instance method in your own Stack class):
public static class MyStackExtensions
{
public static Stack<TDest> Convert<TSrc, TDest>(
this Stack<TSrc> stack,
Func<TSrc, TDest> converter = null)
{
if (stack == null)
throw new ArgumentNullException("stack");
var items = converter == null
? stack.Select(i => (TDest) System.Convert.ChangeType(i, typeof (TDest)))
: stack.Select(converter);
return new Stack<TDest>(items.Reverse());
}
}
Convert stack from int to long using convert function - no type params needed :-)
var intStack = new Stack<int>(new[] { 1, 2, 3 });
var longStack = intStack.Convert(i => (long)i);
Or using standart conversion:
var intStack = new Stack<int>(new[] { 1, 2, 3 });
var longStack = intStack.Convert<int, long>();
Upvotes: 1
Reputation: 64943
No, because class-level generic type parameters can't be auto-infered from usage.
I would imagine that the compiler can deduce that Q is long and T is int in the Convert function, but it doesn't seem to work.
Maybe, but at the end of the day, a generic type parameter doesn't belong to constructor. That is, you provide a generic argument to the type based on what constructor parameter/argument? What happens if there're more than a constructor parameter?
public class A<T>
{
// Which one should be used to auto-infer T from usage?
// Maybe the integer? Or the bool? Or just the string...?
// Every choice seems a joke, because it would be absolutely
// arbitrary and unpredictable...
public A(int x, string y, bool z)
{
}
}
Now take your sample code as example. It has the same issue: what argument should be used from your Convert
static method to infer generic type argument from usage? What happens if Convert
has more than an argument...?
Upvotes: 3