C# 转换泛型类型(如 C++ 用户定义的转换)

C# cast generic type (like C++ user defined conversions)

C# 中有没有一种方法可以为泛型类型执行用户定义的转换?

例如:

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);

我想编译器可以在 Convert 函数中推断出 Q 是 long 而 T 是 int,但它似乎不起作用。

否,因为 class 级泛型类型参数无法根据用法自动推断。

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.

也许吧,但归根结底,泛型类型参数不属于构造函数。也就是说,您根据什么构造函数 parameter/argument 向类型提供通用参数?如果不止一个构造函数参数会怎样?

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)
    {
    }
}

现在以您的示例代码为例。它有同样的问题:应该从你的 Convert 静态方法中使用什么参数来从用法中推断泛型类型参数?如果 Convert 有多个参数...会怎样?

这里是standart Stack的扩展方法class(你可以稍微重写它并在你自己的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());
    }
}

使用转换函数将堆栈从 int 转换为 long - 不需要类型参数:-)

var intStack = new Stack<int>(new[] { 1, 2, 3 });
var longStack = intStack.Convert(i => (long)i);

或使用标准转换:

var intStack = new Stack<int>(new[] { 1, 2, 3 });
var longStack = intStack.Convert<int, long>();