2016-08-29 12 views
5

これらの2つのコンストラクタを1つにマージする方法はありますか?基本的には、同じ配列Point3Dを受け入れます。paramsとIList <T>コンストラクタのマージ

public Curve(int degree, params Point3D[] points) {} 

public Curve(int degree, IList<Point3D> points) {} 

ありがとうございます。

+1

第1の電話に第2の電話をかけますか? –

+1

'params'機能(単一の値を使用して)をサポートしたい場合、それらをマージすることはできません。すべての 'Point3D []'は 'IList 'ですが、 'IList 'のすべてが配列ではありません。したがって、 'params'コンストラクタに' IList'コンストラクタを呼び出させることができます: 'this(degree、(IList )points)' –

答えて

0

、問題は単純に次の操作を行うことができないということです。

public Curve(int degree, params Point3D[] points) 
      : this(degree, points) //want to chain to (int, IList<Point3D>) constructor 
{ 
} 

public Curve(int degree, IList<Point3D> points) 
{ 
} 

次のコンパイル時にエラーが出るので:Error CS0516 Constructor 'Curve.Curve(int, params int[])' cannot call itself".

あなたがこの問題を回避することができますが単にT[]はを実装しているため、配列この作品appropiateタイプ

public Curve(int degree, params Point3D[] points) 
    : this(degree, (IList<Point3D>)points) 
{ 
} 

への参照をキャストすることにより、。

+0

@ CSharpieいいえ、それは正確に答えの全体の点です。 'CS0516'(コンストラクタ自身を呼び出す)のために直接連鎖は機能しません。明示的なキャストは、この問題を避けるためです。 downvotingする前に、少なくとも完全な答えを読むための優しさを持っています。 – InBetween

+0

その夏。あなたがその答えを編集しない限り、私はdownvoteを削除することはできません。私は何を考えていたのか分かりません。 – CSharpie

+0

この答えがどのように違うのか混乱し、同じことを説明した先の回答を追加します。 –

4

あなたはあなたができる2つの異なるコンストラクタ持つようにしたい場合:

public Curve(int degree, params Point3D[] points) : this(degree, (IList<Point3D>)points) { } 
public Curve(int degree, IList<Point3D> points) { } 

するか、したい場合のみ、1つのコンストラクタは、最初は、あなたがこのように初期化することができると言うことができます:1を有することにより

new Curve(0,new List<Point3D>().ToArray()); 

もう一方を呼び出すコンストラクターでは、すべてのロジックを複製する必要はなく、どちらの形式の初期化も有効にします。

public Curve(int degree, Point3D[] points) 
{ 
    ... 
} 

public Curve(int degree, IList<Point3D> points) 
{ 
    ... 
} 

すると、使用できるより:compiler ...... cannot call itself

enter image description here

+2

これは逆です。コレクション全体をコピーする代わりにキャストのみが必要です。 –

+0

@Dennis_E - corrected :) –

+0

@CSharpie - Arrayはそれを実装しているが、それがなければ 'コンストラクタ........自身を呼び出せません 'というコンパイルエラーがあることに同意します。 –

1

が、それはこのように見えた場合:Arrayものの


はのエラーをコンパイルする(IList<Point3D)原因を除去することはできませんIList<T> 1を実装します。 (あなたがコレクターだけを反復する必要がある限りその含まPoint3Dのためション)

public Curve(int degree, IEnumerable<Point3D> points) 
{ 
    ... 
} 

しかし、あなたはあなたがそのようなコンストラクタを呼び出すことができなくなりますので、それは不可能行うためというparamsコンストラクタを持っていると思いますので、:

Curve curve = new Curve(30, p1, p2, p3); 

しかし、唯一のそのような:

Curve curve = new Curve(30, new Point3D[] {p1, p2, p3}); 

public Curve(int degree, params Point3D[] points) 
{ 
    ... 
} 
public Curve(int degree, IList<Point3D> points) : this(degree, points.ToArray()) { } 

または他の方法で回避を::あなたは使用して自分のコードを再利用することができ、それはList 1を使用していますparamsコンストラクタと同じ方法を使用してインスタンスを初期化します

public Curve(int degree, IList<Point3D> points) 
{ 
    ... 
} 
public Curve(int degree, params Point3D[] points) : this(degree, points as IList<Point3D>) { } 

P.S:あなたは、そのクラスのユーザーは、より抽象的にそれを使用できるようにするために、とにかくIEnumerableIListを変更することを検討することをお勧めします。私が正しくあなたを理解していた場合

+0

最後の例のToListは冗長です。 – CSharpie

+0

そうでなければ、コンパイラはこのコンストラクタが自分自身を呼び出すと考えます。 –

+0

あなたは正しいです、私はそれを忘れていました。しかし、IList にキャストする方が良いので、コレクション全体をコピーする必要はありません。 – CSharpie

関連する問題