views:

110

answers:

4
Public class ClassB : ClassA
{
}

public class GeneralClass
{
   public ClassA test
   {
      get{}
      set{}
   }
}
public class specificClass :GeneralClass
{
   public ClassB test
   {
      get{}
      set{}
   }
}

As you can see the property test is inherited in specificClass from generalClass but here I want to change the type to ClassB (ClassB:ClassA) . can I do something like this so anytime I'm using the specializedClass.test I don't need to typecast it to classB ?

edit 1 : I forgot to mention that now it's giving me the warning that test hide inherited member test .use new keyword if hiding is intended .

+6  A: 

You can't modify the return type as you override methods and properties. C# doesn't support return type covariance.

By the way, if you don't need to override the property and just want to return the base value casted to some specific type, you can declare a new property to hide the base class one. Note that it's not return type covariance. It's just a distinct property that happens to have an identical name:

public new ClassB test {
     get { return base.test as ClassB; }
     set { base.test = value; }
}
Mehrdad Afshari
A: 

When overridding methods and properties, you have to use the exact same types as the base method/property, even when it may be safe to use a subclass. You can hide properties using the new keyword, but it won't be virtually dispatched when it is called on the base class.

thecoop
A: 

Mehrdad Afshari just updated his question to reflect what I was about to write. Basically, what you're looking for is:

    public class ClassA
    {

    }

    public class ClassB : ClassA
    {

    }

    public class GeneralClass
    {
        public ClassA myClass { get; set; }
    }

    public class SpecificClass : GeneralClass
    {
        new public ClassB myClass { get; set; }
    }

    public myFunction()
    {

        var sc = new SpecificClass();

        sc.myClass = new ClassB();

        Console.WriteLine("sc.GetType() = " + sc.myClass.GetType());

        var gc = (GeneralClass)sc;

        gc.myClass = new ClassA();

        Console.WriteLine("gc.GetType() = " + gc.myClass.GetType());

        Console.WriteLine("sc.GetType() = " + sc.myClass.GetType());
    }
JustLoren
A: 

Depending on your exact problem you can solve it with generics. (But it's kind of complicated)

Note: GeneralClass : AbstractGeneralClass and SpecificClass : AbstractGeneralClass

You can:

  • store instances of GeneralClass and SpecificClass in AbstractGeneralClass
  • access testAsClassA if you have a variable of type AbstractGeneralClass
  • access ClassB test if you have a variable of type SpecificClass
 class ClassA { }
    class ClassB : ClassA { }

    abstract class AbstractGeneralClass
    {
     /* functionality that does not depend on test */

     public abstract ClassA testAsClassA { get; }
    }

    abstract class AbstractGeneralClass : AbstractGeneralClass where T : ClassA
    {
     T myProperty;
     public T test
     {
      get { return myProperty; }
      set { myProperty = value; }
     }

     public override ClassA testAsClassA { get { return myProperty; } }
    }

    class GeneralClass : AbstractGeneralClass { }

    class SpecificClass : AbstractGeneralClass { }
Simon Ottenhaus