【问题标题】:C# Cast Entire Array?C# 转换整个数组?
【发布时间】:2010-01-14 22:47:59
【问题描述】:

我看到了这个Array.ConvertAll 方法,但它需要Converter 作为参数。当我已经在我的类中定义了一个隐式转换器时,我不明白为什么我需要一个转换器:

    public static implicit operator Vec2(PointF p)
    {
        return new Vec2(p.X, p.Y);
    }

我正在尝试将PointFs 的数组转换为Vec2s 的数组。有没有很好的方法来做到这一点?还是我应该把它吸起来然后写(另一个)转换器或循环遍历元素?

【问题讨论】:

标签: c# arrays casting


【解决方案1】:

建议的使用Cast/'Select' 的LINQ 解决方案很好,但既然您知道您在这里使用的是一个数组,那么使用ConvertAll 会更有效,而且同样简单。

var newArray = Array.ConvertAll(array, item => (NewType)item);

使用ConvertAll 表示
a) 数组只迭代一次,
b) 对数组的操作更加优化(不使用IEnumerator<T>)。

不要让Converter<TInput, TOutput> 类型混淆您 - 它只是一个简单的委托,因此您可以为它传递一个 lambda 表达式,如上所示。

【讨论】:

  • 完美运行!谢谢!我以为我必须定义<types>
  • 没问题。是的,在 C# 2.0 和之前你必须定义一个类型 - 幸运的是那些日子已经一去不复返了。
  • 嗯,实际上,我相信没有一个提议的解决方案会使数组被迭代两次,因为 Cast 和 Select 都是使用延迟执行实现的:msdn.microsoft.com/en-us/library/…msdn.microsoft.com/en-us/library/…
【解决方案2】:

作为对这个老问题的更新,您现在可以这样做:

myArray.Cast<Vec2>().ToArray();

其中 myArray 包含源对象,而 Vec2 是您要转换为的类型。

【讨论】:

  • 需要命名空间:使用 System.Linq
【解决方案3】:

最有效的方法是:

class A { };
class B : A { };

A[] a = new A[9];
B[] b = a as B[];

【讨论】:

  • 这很快,但b 将永远是null。您不能从A[] 转换为B[],因为A 数组可能包含非B 实例(例如C : A);也就是说,并非每个A 都必然也是B。相反,如果您执行了B[] b = new B[9]; A[] a = b as A[];,那么这将成功,因为您正在从 more-derived 数组类型转换为 less-derived 数组类型。你甚至可以使用A[] a = (A[]) b;,因为as 永远不会失败。更好的是A[] a = b;,因为编译器知道每个B也是一个A,因此每个B[]也是一个A[]
【解决方案4】:

Cast 不考虑用户定义的隐式转换,因此您不能像那样转换数组。您可以使用 select 代替:

myArray.Select(p => (Vec2)p).ToArray();

或者写一个转换器:

Array.ConvertAll(points, (p => (Vec2)p));

后者可能更有效,因为事先知道结果的大小。

【讨论】:

    猜你喜欢
    • 2015-06-29
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 2016-02-27
    • 2017-10-08
    • 2016-04-30
    相关资源
    最近更新 更多