C# 3.0 这个C#casting没用吗?

C# 3.0 这个C#casting没用吗?,c#-3.0,casting,C# 3.0,Casting,我有两种方法: Foo[] GetFoos(Type t) { //do some stuff and return an array of things of type T } T[] GetFoos<T>() where T : Foo { return GetFoos(typeof(T)) as T[]; } Foo[]GetFoos(类型t){//做一些事情并返回一个类型t的数组} T[]GetFoos() T:Foo在哪里 { 将GetFoos(type

我有两种方法:

Foo[] GetFoos(Type t) { //do some stuff and return an array of things of type T }

T[] GetFoos<T>()
    where T : Foo
{
    return GetFoos(typeof(T)) as T[];
}
Foo[]GetFoos(类型t){//做一些事情并返回一个类型t的数组}
T[]GetFoos()
T:Foo在哪里
{
将GetFoos(typeof(T))返回为T[];
}
然而,这似乎总是返回null。我做错事情了吗?还是这只是C#的短缺

注意: 我知道我可以通过以下方法解决此问题:

GetFoos(typeof(T)).Cast<T>().ToArray();
GetFoos(typeof(T)).Cast().ToArray();
然而,我更愿意在不进行任何分配的情况下完成这项工作(在对垃圾收集非常敏感的环境中工作)

Nb++: 如果您建议其他非分配解决方案,则可获得额外积分

编辑:
这提出了一个有趣的问题。这里的MSDN文档:如果存在隐式或显式强制转换,则强制转换将成功。在这种情况下,有一个显式强制转换,因此强制转换应该成功。MSDN文档是否错误?

如果您可以安排
GetFoos
使用
new T[]
创建返回数组,那么您就赢了。如果您使用了
new Foo[]
,那么数组的类型将固定在该位置,而不管它实际包含的对象的类型是什么。

如果您可以安排
GetFoos
使用
new T[]
创建返回数组,那么您就赢了。如果您使用了
new Foo[]
,那么数组的类型将固定在该位置,而不管它实际包含的对象的类型是什么。

不,C#强制转换不是无用的-您不能将
Foo[]
强制转换为
t[]
其中
t
是一种更派生的类型,正如
Foo[]
可能包含与
T
不同的其他元素。为什么不将
GetFoos
方法调整为
GetFoos()
?只接受
类型
对象的方法可以很容易地转换为通用方法,您可以通过
newt[]
直接创建数组

如果这是不可能的:您是否需要数组提供的功能(即索引和类似于
计数的功能)
?如果没有,您可以使用
IEnumerable
,而不会有太多问题。如果没有:您将无法绕开
Cast.ToArray()
的道路

编辑:

没有可能从
Foo[]
T[]
,链接中的描述是相反的-你可以将
T[]
转换为
Foo[]
,因为所有
T
都是
Foo
,但并非所有
Foo
都是
T

不,C>转换不是无用的-你根本不能转换
Foo[]
T[]
其中
T
是一个更派生的类型,因为
Foo[]
可能包含与
T
不同的其他元素。为什么不将
GetFoos
方法调整为
GetFoos()
?仅采用
类型
对象的方法可以轻松转换为通用方法,您可以通过
newt[]
直接创建数组

如果这是不可能的:你需要数组提供的能力吗(例如索引和类似于
计数的东西)?如果不需要,你可以使用
IEnumerable
,而不会有太多问题。如果不需要,你将无法绕开
Cast.ToArray()
的方法

编辑:


没有可能从
Foo[]
转换到
T[]
,链接中的描述是另一种方式-你可以将
T[]
转换为
Foo[]
,因为所有
T
都是
Foo
,但并非所有
Foo
都是
T

我没有尝试过这一点,但应该可以:

T[] array = Array.ConvertAll<Foo, T>(input,
    delegate(Foo obj)
    {
        return (T)obj;
    });
T[]数组=数组.ConvertAll(输入,
代表(Foo obj)
{
返回(T)obj;
});
你可以在


我认为这会转换到位,因此不会进行任何重新分配。

我没有尝试过,但它应该可以工作:

T[] array = Array.ConvertAll<Foo, T>(input,
    delegate(Foo obj)
    {
        return (T)obj;
    });
T[]数组=数组.ConvertAll(输入,
代表(Foo obj)
{
返回(T)obj;
});
你可以在


我认为这是就地转换的,因此不会进行任何重新分配。

根据我对您的情况的了解,使用
系统。数组
代替更具体的数组可以帮助您。请记住,
数组
是所有强类型数组的基类,因此
数组
引用基本上可以存储任何数组y、 您应该将(通用的?)字典映射为
Type->Array
,这样您就可以存储任何强类型数组,而不必担心需要将一个数组转换为另一个数组,现在只需进行类型转换

i、 e

字典myDict=。。。;
数组GetFoos(类型t)
{
//做检查,诸如此类
返回myDict[t];
}
//和一个普通助手
T[]GetFoos()其中T:Foo
{
return(T[])GetFoos(typeof(T));
}
//然后访问特定类型的所有需要强制转换
Foo[]f=(Foo[])GetFoos(typeof(Foo));
DerivedFoo[]df=(DerivedFoo[])GetFoos(typeof(DerivedFoo));
//或者使用泛型帮助器
另一个派生的foo[]adf=GetFoos();
//等等。。。

p、 在美国,您提供的MSDN链接显示了数组是如何协变的。也就是说,您可以在对基类型数组的引用中存储更派生类型的数组。您在这里试图实现的是逆变(即,使用基类型的数组代替更派生类型的数组)这是另一种方法,数组不进行转换就不能做什么。

根据我对您的情况的了解,使用
系统。数组
代替更具体的数组可以帮助您。请记住,
数组
是所有强类型数组的基类,因此
数组
引用基本上可以存储任何数组。您应该将(通用的?)字典映射为
Type->array
,这样您就可以存储任何强类型数组,而不必担心需要将一个数组转换为另一个数组,现在只需进行类型转换

i、 e

字典myDict=。。。;
数组GetFoos(类型t)
{
//做检查,诸如此类
R