ConvertAll
明確にするために、ConvertAll の使用方法を次に示します。
whereがcalledclass B
のメンバーである場合は、次のようにします。class A
m_a
B[] arrB;
A[] arrA = Array.ConvertAll(arrB, b => b.m_a);
.
タイプ A のオブジェクトを返す前に操作する必要があるメンバー データがある場合class B
(一連の数値を文字列の説明に変換するなど)、次のようにします。
class B
{
public static A makeAfromB(B b)
{
// Do something with B data...
A a = new A("data made from B data")
return a;
}
// rest of class B implementation ...
}
// somewhere else in your code...
A[] arrA = Array.ConvertAll(arrB, new Converter<B, A>(B.makeAfromB));
.
Lambda 関数を使用することもできます。
A[] arrA = Array.ConvertAll(arrB, new Converter<B, A>(
delegate(B b)
{
// Do something with B data, though object b is const
A a = new A("data made from B data")
return a;
}));
.
ConvertAll が暗黙の演算子を使用して変換を実行できればいいのですが、その方法がわかりません。
.
キャスト
@ランドルフォ @bottlenecked
単に反復したいだけで、コピーを作成したくない場合は、キャストを使用するのが理にかなっています。しかし、私はそれを機能させることができませんでした。
オブジェクトと他のメンバーを持つInkPoint
クラスがあります。関数Point
を呼び出したい。DrawLines(Pen, Point[])
ただし、の配列がありInkPoint[]
ます。
これが私のクラスと私が現在使用しなければならないコードで、コピーを作成します:
public class InkPoint
{
public InkPoint(int x, int y)
{
point = new Point(x, y);
}
public Point point { get; set; }
public static implicit operator Point(InkPoint p)
{
return p.point;
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
InkPoint[] inkPoints = { new InkPoint(1,2), new InkPoint(3,4) };
Point[] points = Array.ConvertAll(inkPoints, x => x.point);
Pen pen = new Pen(Color.Black, 1);
e.Graphics.DrawLines(pen, points);
}
.
私はむしろこれを呼び出したいのですが、無効な引数を引用してコンパイルされません:
e.Graphics.DrawLines(pen, inkPoints.Cast<Point>()); // Compile err: invalid args
.
また、キャストを反復しようとしましたが、キャストが無効であることを理由に例外がスローされます
foreach (Point p in inkPoints.Cast<Point>()) { } // Exception: cast not valid
.
specified cast is not valid
暗黙の演算子を定義したので、その理由がわかりません。私は次のことをうまく行うことができます:
InkPoint ip = new InkPoint(10, 20);
Point p1 = ip; // implicit conversion
Point p2 = (Point)ip; // cast
.
私にとって、状況は実際にはそれよりも少し複雑です。実際には InkPoints のリストを持っていますList<InkPoint>
が、このDrawLines
関数は配列しか受け入れません。したがって、私のコードは次のようになります。
List<InkPoint> inkPoints = new List<InkPoint>();
inkPoints.Add(new InkPoint(5, 10));
inkPoints.Add(new InkPoint(10, 15));
Point[] points = inkPoints.ConvertAll<Point>(x => x.point).ToArray();
これを少し並べ替えることができます:
Point[] points = Array.ConvertAll(inkPoints.ToArray(), x => x.point);
.
つまり、実際にはここで 2 つのコピーが発生していると思います。私がやりたいのは線を描くことだけなので、これは面倒です。DrawLines
関数が、暗黙的にオブジェクトに変換できるオブジェクトへの参照を含む配列/リストを反復処理できる必要があることは、不合理ではないようPoint
です。