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