I'll explain the reason I am trying to do this first. My Initial Hierarchy:

BaseClass
   |
ControlClass
   |     \
CalltoBase  DerivedClass1
              |
            CalltoBase

Both call paths hit a particular method of the base class Depending on where the CalltoBase originates I need to use a different implementation of that one method. This is what I normally would have done:

BaseClass____DerivedClass2
   |              |      
ControlClass   ControlClass2
   |    \             |    \
 call DerivedClass1  call  DerivedClass3
          call                 call

The problem is that this project is growing and there will be necessity for even more implementations of that one method in the base class. Hence my reason for wanting to do something like this, I would like to only have to create 1 extra derived class instead of three every time I run into this.

BaseClass
  |      \______
ControlClass<t> \_____           
 |    \               \
call DerivedClass1<t>  tClass
       call

Note: every line except the call lines are inheritance I do not have the authority or the time to change the system so that they would not be inheritance.

my goal is to do something like this:

public class BaseClass{code}
public class tClass : BaseClass {code}
public class ControlClass<t> : t where t : BaseClass {code}
public class DerivedClass1<t> : ControlClass<t> where t : BaseClass {code}
//defaults
public class ControlClass : ControlClass<BaseClass> {empty}
public class DerivedClass1 : ControlClass<BaseClass> {empty}

Is something like this possible or should I just accept that I'm screwed and make all of the derivative classes every time?

Edit1***************************************** After doing some more research I think my real question is: How can I use Dependency Injection to either Override a method or to set a default method when no dependency is explicitly injected?

Edit2******************************************

This code is all inside of a library that the company created and is used by many projects. It is for UAT's using selenium/specflow.

public class BaseClass
{
   public T Control<T>(string controlName, string pageName = null) 
                      where T : class
   {
      By sel = GetSelector(controlName, pageName)
      ...
      return control as T;
   }
   private By GetSelector(string controlName, string pageName = null)
   {
      pageName = string.IsNullOrEmpty(pageName) ?
                 pageMapping[Browser.GetPage()] : pageName;
      ...
      return selector;
   }
}
public class ControlClass : BaseClass
{
   public NgElement NgControl(string controlName, string pageName)
   {
      By sel = GetSelector(controlName, pageName);
      ...
      return element;
   }
   public By GetSelector(string controlName, string pageName)
   {
      pageName = string.IsNullOrEmpty(pageName) ? PageName : pageName;
      pageName = string.IsNullOrEmpty(pageName) ?
                            pageMapping[Browser.GetPage()] : pageName;
      ...
      return selector;
   }
   public string PageName
   {
      get
      {
         ...
         return returnPage.Value;
      }
   }
}
public class DerivedClass1 : ControlClass
{
   //SpecFlow GWT's
   GivenAngularClicks(string controlName)
   {
      WaitForAngular();
      NgControl(crontrolName).Click();
   }
}

The parts that change pageName are the parts that need to be modified based on which project is the caller. It doesn't matter which derived class makes the call, what matters is the class that instantiates base class.

3

There are 3 answers

1
Bart van der Drift On

Shouldn't something like this be possible by using overrides, in which you call different methods on the base class? Something like:

public class BaseClass
{
    public virtual void FunctionA() { ... }
    public void FunctionAVariant1() { ... }
    public void FunctionAVariant2() { ... }
}

public class DerivedClass1 : BaseClass
{
    public override void FunctionA()
    {
        base.FunctionAVariant1();
    }
}

public class DerivedClass2 : BaseClass
{
    public override void FunctionA()
    {
        base.FunctionAVariant2();
    }
}
2
comdiv On

I think it's better in your case make more complicated base class - your hierarchy looks like inhertiance used to provide some helper and secondary functionality. May be better to split it horizontally to services and make aggregates instead of making hard-to-understand mixed generic hierarchy?

May be u use only .ctors in classes to initialize and it can be changed to Factory?

Why you so sure that u must to have split-and-then-merge hierarchy?

Bad design cause bad questions. You can do anything with inheritance and generics, but think better if you have to do this...

0
Bart van der Drift On

Maybe you could check to see what type you are in the base class.

public class BaseClass
{
    public void Call()
    {
        if (this is DerivedClass<int>)
        {
            CallInt();
        }
        else if (this is DerivedClass<string>)
        {
            CallString();
        }
        else
        {
            Console.WriteLine("Base class");
        }
    }

    public void CallInt()
    {
        Console.WriteLine("It's an int");
    }

    public void CallString()
    {
        Console.WriteLine("It's a string");
    }
}

public class DerivedClass<T> : BaseClass {

}

public class Program
{
    public static void Main()
    {
        var intClass = new DerivedClass<int>();
        var stringClass = new DerivedClass<string>();
        intClass.Call(); // writes 'It's an int'
        stringClass.Call(); // writes 'It's a string'
    }
}