2

I would like to write a method that works sort of like this:

public class BaseClass {}
public class DerivedClass1 : BaseClass {}
public class DerivedClass2 : BaseClass {}

public class BaseClassCreator
{
    public static T Create<T>() where T : BaseClass
    {
        if( T is DerivedClass1 ) return new DerivedClass1();
        if( T is DerivedClass2 ) return new DerivedClass2();

        return null;
    }
}

I am getting compiler errors saying I can not converted DerivedClass1 to T. How do I need to write this method to do the following:

BaseClass x = BaseClassCreator.Create<DerivedClass1>();
BaseClass y = BaseClassCreator.Create<DerivedClass2>();
5
  • Also, wouldnt this be a whole lot easier if you did return (T)Activator.CreateInstance(typeof(T)) ? Commented Feb 8, 2012 at 16:45
  • Is your real code that simple? If it is then you're not really doing anything the Activator.CreateInstance<T>() method doesn't do. Commented Feb 8, 2012 at 16:45
  • Not that simple. It was just to demonstrate the error I was getting. Commented Feb 8, 2012 at 16:52
  • CodeInChaos is right; this looks like an abuse of generics. If the factory can create only n kinds of things then it is not generic, so do not make it a generic factory. Make a factory with n different CreateDerived1, CreateDerived2, etc, methods. Commented Feb 8, 2012 at 17:05
  • @EricLippert I was just doing this out of curiosity. I realize it is an abuse. Commented Feb 8, 2012 at 17:11

3 Answers 3

4

This looks like a case where you could just leverage the new() constraint

public static T Create<T>() where T : BaseClass, new()
{
  return new T();
}
Sign up to request clarification or add additional context in comments.

Comments

3

The is (and as) keywords operate on instances, not types. Im guessing what you actually wanted was

if(typeof(T) == typeof(DerivedClass1)) ....

Comments

3

First of all, a is T only works if the left side is an instance, not a type. So you need to apply typeof(T) on both sides. And then either use == if you want to check if the types are identical, or IsAssignableFrom(...) to check if one is derived from the other. In Your case you probably want ==.

The casts only work if you insert a known base type. Which can be object or BaseClass.

public static T Create<T>() where T : BaseClass
{
    if( typeof(T) == typeof(DerivedClass1 )) return (T)(BaseClass)new DerivedClass1();
    if( typeof(T) == typeof(DerivedClass2 )) return (T)(BaseClass)new DerivedClass2();

    return null;
}

But I'm not sure if this is a good idea in the first place. This code isn't really generic since it only works for a few classes you hardcoded.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.