1

次のクラス構造を想像してみましょう。

    class A{
        public double X;
        public double Y;

        public A(double x, double y){
            X=x; Y=y;
        };   
        public A MiddlePoint(A[] a){
            A resultPnt = new A(0,0);
            for (int i = 0; i < a.Length; i++){
                resultPnt.X += a[i].X;
                resultPnt.Y += a[i].Y;
            }
            resultPnt.X = (this.X + resultPnt.X)/(a.Length + 1);
            resultPnt.Y = (this.Y + resultPnt.Y)/(a.Length + 1);
        }
    }

    class B:A{}

このような方法を使用するのは安全ですか:

B b = new B();
B[] arr = new B[2];
b.MiddlePoint(arr);

? そうでない場合、クラス B でオーバーロードする以外に、このメソッドを安全に呼び出すにはどうすればよいですか? 継承されたすべてのクラスでこのメソッドを毎回オーバーロードするのは便利ではありません。

PS 安全性とは、いかなる場合でも例外をスローしないことを意味します。

4

2 に答える 2

1

はい、コードは C# で動作するはずです。(少なくとも、C# 4.0 の下の私のマシンでは、引数なしのコンストラクターをA. に追加すると、そのようなものがコンパイルされます)。

書かれたコードはA、 の任意のサブタイプの配列で渡されると、 のインスタンスを返しますA。たとえば、Bの配列を渡すときに代わりにのインスタンスを取得することを主張する場合Bは、次のようなジェネリックを使用できます。

class A{
    public double X;
    public double Y;

    public A(double x, double y){
        X=x; Y=y;
    }
    public A(){
        // needs to have a no-arg constructor to satisfy new() constraint on MiddlePoint
    }
    public T MiddlePoint<T>(T[] a) where T : A, new() {
        T resultPnt = new T();
        for (int i = 0; i < a.Length; i++){
            resultPnt.X += a[i].X;
            resultPnt.Y += a[i].Y;
        }
        resultPnt.X = (this.X + resultPnt.X)/(a.Length + 1);
        resultPnt.Y = (this.Y + resultPnt.Y)/(a.Length + 1);
    }
}

class B:A{}
于 2013-11-13T10:17:59.007 に答える
1

のタイプの新しい配列を作成し、配列内のAすべてのインスタンスをBアッパーキャストしAてその配列に挿入するようなものです。その後、そのA型オブジェクトの配列をメソッドに渡します。

したがって、これは意図したとおりに動作します。

詳細については、共分散と反分散を参照してください。

于 2013-11-13T10:13:14.640 に答える