2

I'm trying to create a set of classes with different level of abstraction. I will use the Vector example here.

My goal is that the user of my classes can choose the level of abstraction to use i.e. they may or may not want to be using the more derived class.

interface IVector
{
    Vector A();
}

interface ISparseVector : IVector
{
    new SparseVector A();
}

Now, I implement the classes as such:

class Vector : IVector
{
    public Vector A() { return new Vector(); }
}

class SparseVector : Vector,ISparseVector
{
    public new SparseVector A() { return new SparseVector(); }
}

This is all fine and dandy. However, when the base class is abstract such as:

abstract class Vector : IVector
{
    public abstract Vector A();
}

class SparseVector : Vector,ISparseVector
{
    public SparseVector A() { return new SparseVector(); } // Hides abstract member.
}

I get a compile error saying that the derived method is hiding the abstract method in Vector. Any idea of how to get around this?

Johan Tidén
  • 664
  • 7
  • 19
  • You asked in a comment to an answer below whether there is a hack to solve it anyway: I've found one (using generic covariance), but unfortunately, it doesn't work if your return type is the same as the enclosing class, so it doesn't help in your specific case. – Alex ten Brink Jan 23 '12 at 13:21

4 Answers4

6

The feature you want is called "return type covariance", and it is not a feature of C#. Return type covariance is the feature where you can have a virtual method that return an Animal, and then you override that with a method that returns a Giraffe.

Doing so is typesafe and some languages do have this feature -- C++ for example -- but C# does not and we have no plans to add it. Your overriding method has to be marked override, and it has to match exactly -- in name, formal parameter types, and return type.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    Thank you. How come there are no plans to add it? – Johan Tidén Jan 23 '12 at 01:59
  • @swejtsys: Those are frequently asked questions; if you search the site for "C# return type covariance" you'll find plenty of information about it. Maybe start here: http://stackoverflow.com/questions/5709034/does-c-sharp-support-return-type-covariance/5709191#5709191 – Eric Lippert Jan 23 '12 at 03:41
1

The reason is in your first example on the Vector class, you weren't specifying an access level for the A() method. This means it is a private method, which is the default. You could use the new keyword in the SparseVector class to get around this error.

SoWeLie
  • 1,381
  • 12
  • 16
  • Thank you, I made some misstakes in the example. I will edit it. The main question still remains though. – Johan Tidén Jan 23 '12 at 01:48
  • If you use the new keyword on your A() method of your SparseVector class, it will work, although in general if you're using the new keyword there's probably a better way to to what you're trying to do. – SoWeLie Jan 23 '12 at 01:50
0

For a start, you should look at this thread which specifies why you cannot have an abstract constructor.

Why can't I create an abstract constructor on an abstract C# class?

Then, you should put an abstract method in your Vector class that can actually be overridden to provide implementation, as abstract methods are supposed to be.

Community
  • 1
  • 1
3Pi
  • 1,814
  • 3
  • 19
  • 30
  • Apologies, misread and assumed. However, you still need to add override to SparseVector to give public override SparseVector A() – 3Pi Jan 23 '12 at 01:49
  • I can't add override since it has another return type than the abstract method. – Johan Tidén Jan 23 '12 at 02:08
0

You can't mix abstract and interface methods the way you're trying. If you were to declare 'Vector' abstract and override the implementation of A(), you'd be overriding 'Vector A()' from your abstract class, but that wouldn't implement the interface ISparseVector.Vector, which has a return type of ISparseVector.

Your use-case doesn't appear to require that 'Vector' be abstract.

Val Akkapeddi
  • 1,173
  • 10
  • 17