简体   繁体   中英

C#. How can I use a method described in a base class with the arguments of inherited class?

Lets imagine the following structure of classes:

    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{}

Is it safety to use method like this :

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

? If not, what should I do to make this method call safety except overloading it in the class B? It is not convenient every time overload this method in every inherited class.

PS Safety means without throwing exception in any case.

It's like you create a new array of type of A , and every instance of B in your array uppercast to A and insert in that array. After pass that array of A type objects to the method.

So this is as it intended to work.

More on this you can find on: Covariance and Contravariance

Yes, your code should work in C#. (At least, something like it compiles on my machine under C# 4.0, once you add a no-arg constructor to A .).

Your code as written will return an instance of A when passed in an array of any subtype of A . If you insist on, for example, getting back an instance of B instead when you pass in an array of B , you could use generics, similar to the following:

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{}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM