Search code examples
c#inheritancesubclasssuperclass

C# How could a superclass return back 3 possible types without casting from the calling class


Before I begin, I want to state I realize this isn't the ideal way of doing this. However the calling class can't be changed according to the rules of the assignment. I have tried to understand and find a solution to this problem, but I have had no luck.

Below there is 1 superclass,TreeMangement (There can only be 1 superclass for these subclasses). There are 3 subclasses(apple, orange and banana). The "find" method must be in the TreeMangement superclass. I am not allowed to override the "find" method. With the current code, I will get a casting error in the calling class. It will state that a TreeMangement can't implicity be casted into a AppleTree,OrangeTree or BananaTree.

Now my question is, am I able to somehow pass the correct type back to the calling class no matter what type (Apple,Banana,Orange) is calling it, without casting in the calling class? If so, how? If not, references so I know there is absolutely no way of doing it.

public class TreeMangement
{
    public string id {get; set;}

    public TreeMangement()
    {
       id = this.GetType().Name+"|"+Guid.NewGuid();
    }

    public static TreeMangement Find(string idIn)
    {
       string type = idIn.Split('|')[0];
       return Functions.GetObj(idIn, GetFilePath(type), type); //returns back the right type
    }
}




public class AppleTree:TreeMangement
{
     public string Name;
}  

public class OrangeTree:TreeMangement
{
     public string Name;
}

 public class BananaTree:TreeMangement
{
     public string Name;
}  


///////Calling class//// 

AppleTree savedAppleTree = AppleTree.Find("SomeValidID");
OrangeTree savedOrangeTree = OrangeTree.Find("SomeValidID");
BananaTree savedBananaTree = BananaTree.Find("SomeValidID");

Solution

  • You can change the superclass to a generic superclass like this:

    public class TreeMangement<T>
      where T: class
    {
        ...
    
        public static T Find(string idIn)
        {
           return ... as T;
        }
    }
    

    Now you are able to specifiy the return type in your subclasses like

    public class AppleTree:TreeMangement<AppleTree>
    {
         public string Name;
    }  
    
    public class OrangeTree:TreeMangement<OrangeTree>
    {
         public string Name;
    }
    
     public class BananaTree:TreeMangement<BananaTree>
    {
         public string Name;
    }
    

    This way your 3 find calls will compile just fine as the Find() call will return the correct type:

    var savedAppleTree = AppleTree.Find("SomeValidID");
    var savedOrangeTree = OrangeTree.Find("SomeValidID");
    var savedBananaTree = BananaTree.Find("SomeValidID");