C# 中的隐式数组转换
我有以下定义了隐式转换运算符的类:
class A
{
...
}
class B
{
private A m_a;
public B(A a)
{
this.m_a = a;
}
public static implicit operator B(A a)
{
return new B(a);
}
}
现在,我可以将 A 隐式转换为 B。
但是为什么我不能将 A[] 隐式转换为 B[] ?
static void Main(string[] args)
{
// compiles
A a = new A();
B b = a;
// doesn't compile
A[] arrA = new A[] {new A(), new A()};
B[] arrB = arrA;
}
谢谢,马尔基。
I have the following classes with an implicit cast operator defined:
class A
{
...
}
class B
{
private A m_a;
public B(A a)
{
this.m_a = a;
}
public static implicit operator B(A a)
{
return new B(a);
}
}
Now, I can implicitly cast A to B.
But why can't I implicitly cast A[] to B[] ?
static void Main(string[] args)
{
// compiles
A a = new A();
B b = a;
// doesn't compile
A[] arrA = new A[] {new A(), new A()};
B[] arrB = arrA;
}
Thanks, Malki.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如 Mehrdad Afshari 提到的,你隐式地这样做是不走运的。您必须明确说明,并且它将涉及数组副本。值得庆幸的是,您可能可以用一行代码来完成:
尽管如果您只想在
foreach
语句中迭代arrB
,则可以通过省略来避免复制ToArray()
As Mehrdad Afshari mentioned, you're out of luck doing this implicitly. You'll have to get explicit, and it'll involve an array copy. Thankfully, you can probably do it with a one-liner:
Although if you only want to iterate
arrB
in aforeach
statement, you can avoid the copy by omittingToArray()
数组协变仅适用于引用类型和继承层次结构(请注意,它不是表示更改的转换:只是一组具有相同大小的指针,其解释不同。)它不适用于值类型和用户定义的转换。
Array covariance only works for reference types and in the inheritance hierarchy (note that it's not a representation-changing conversion: just a set of pointers with identical size interpreted differently.) It will not work for value types and user defined conversions.
ConvertAll
明确地说,以下是使用 ConvertAll 的方法。
如果
B 类
有一个名为m_a
的A 类
成员,请执行以下操作:。
如果
B类
有一些成员数据,您需要在返回A类型的对象之前对其进行操作(例如将一堆数值转换为字符串描述),请执行以下操作:。
您还可以使用 Lambda 函数:
.
如果 ConvertAll 可以使用隐式运算符来进行转换,那就太好了,但我还没有弄清楚如何做到这一点。
。
Cast
@Randolpho @bottlenecked
对于您只想迭代并且不想制作副本的情况,使用cast 是有意义的。然而我一直无法让它发挥作用。
我有一个
InkPoint
类,它有一个Point
对象和一些其他成员。我想调用DrawLines(Pen, Point[])
函数。但是,我有一个InkPoint[]
数组。这是我的类和我当前必须使用的代码,它会生成一个副本:
。
我宁愿这样称呼它,但它不会编译,引用无效的参数:
。
我也尝试过迭代强制转换,但它抛出异常,引用强制转换无效
。
我不明白为什么
指定的转换无效
,因为我定义了一个隐式运算符。我能够很好地执行以下操作:。
对我来说,情况实际上比这稍微复杂一些。我实际上有一个 InkPoints 列表,
List
,但DrawLines
函数仅接受数组。所以我的代码看起来像这样:我可以将其稍微重新排列为:
。
所以我认为这里实际上发生了两个副本。这很烦人,因为我只想画线。
DrawLines
函数应该能够迭代某些包含可隐式转换为Point
对象的对象引用的数组/列表,这似乎并非不合理。ConvertAll
Just to be explicit, here is how you use ConvertAll.
In the case where
class B
has a member ofclass A
calledm_a
, do this:.
If
class B
has some member data that you need to manipulate before you can return an object of type A (such as turning a bunch of numerical values into a string description), do this:.
You can also use Lambda functions:
.
It would be nice if ConvertAll could use the implicit operator to do the conversion, but I haven't figured out how to do that.
.
Cast
@Randolpho @bottlenecked
For the cases where you simply want to iterate and would prefer not to make a copy, using cast makes sense. However I have been unable to make it work.
I have an
InkPoint
class which has aPoint
object and some other members. I want to call theDrawLines(Pen, Point[])
function. However, I have an array ofInkPoint[]
.Here is my class and the code I currently have to use, which makes a copy:
.
I would rather call this, but it won't compile, citing invalid arguments:
.
I've also tried iterating over a cast, but it throws an exception, citing the cast is not valid
.
I don't understand why the
specified cast is not valid
since I've defined an implicit operator. I'm able to do the following just fine:.
For me, the situation is actually slightly more complicated than that. I actually have a list of InkPoints,
List<InkPoint>
, but theDrawLines
function accepts only arrays. So my code looks like this:I can rearrange it slightly to this:
.
So I think there's actually two copies happening here. This is annoying since all I want to do is draw the lines. It doesn't seem unreasonable that the
DrawLines
function should be able to iterate over some array/list that contains references to objects that can be implicitly converted toPoint
objects.想象一下,如果数组使用与 .Net 中其他集合相同的语法,并且您尝试比较的是
Array
和Array
>。您不会将List
与
List
进行比较。嗯,这本质上就是你正在尝试的。我建议使用简单的扩展方法来获得您想要的结果,您需要稍微更改语法以表示 'B[] arrB = arrA.ToBArray();`
Imagine for a moment if Arrays used the same syntax as other collections in .Net, and what you're trying to compare is an
Array<A>
with anArray<B>
. You wouldn't compare aList<A>
to aList<B>
. Well, that's essentially what you're trying.I'd recommend using a simple extension method to get the result you want, you'll need to change your syntax slightly to say 'B[] arrB = arrA.ToBArray();`