Abstract class and new() used as constraints; return type parameter issue

120 views Asked by At

I have very interesting problem for me.

I have abstract class like this:

abstract class BaseAbstract
{
  … some abstract stuff.
}

I have some derived types. So, they look like this:

class DerivedOneA
{
  … abstract stuff implementation.
}

I have some generic type like this:

class GenericOne<T> where T: BaseAbstract, new()
{
  GenericOne()
  {
    var type =  new T();
    … some code with type.
  }
}

I have problem like this:

class SomeClass
{
  GenericOne<T> GetGenericOne<T>() where T : BaseAbstract, new()
  {
    var x = CreateGenericOne<DerivedOneA>(); // Okay.

    //return new GenericOne<DerivedOneA>(); // Not okay. Cannot convert
    // GenericOne<DerivedOneA> to GenericOne<T>.
    // return x; // Not okay. The same as return before.

    throw new Exception();
  }    

  GenericOne<T> CreateGenericOne<T>() where T : BaseAbstract, new()
  {
    return new GenericOne<T>();
  }
}

I need something like this:

class SomeClass
{
  GenericOne<T> GetGenericOne<T>() where T : BaseAbstract, new()
  {
    switch(desiredType)
    {
      case A:
        return new GenericOne<DerivedOneA>();
      case B:
        return new GenericOne<DerivedOneB>();

       … 

      default:
        throw new ArgumentException();
    }
  }

I think the problem is that I do not know and I could not find out how to tell to compiler that the DerivedOne classes do comply to constraints in case T is known to it at compile time.

Alternative solutions are also welcome.

2

There are 2 answers

0
Yarl On BEST ANSWER

It is no possible to use generic type parameter along with explicit type parameter in one place.

0
Callback Kid On

Following up on Jon Skeets comment, when you call GetGenericOne you need to give it a type argument to fulfill the T

var theGenericOne = GetGenericOne<DerivedOneA>();

This means in your GetGenericOne<T>() it should look like

GenericOne<T> GetGenericOne<T>() where T : BaseAbstract, new()
{
  var x = new CreateGenericOne<T>(); // Okay.
  return x;
}