tags:

views:

94

answers:

6

Is there a way to specify that a generic type be of one type or another type?

public class SoftDrink<T>
    where T : TypeOne or TypeTwo
{ }
+1  A: 

No, however, you could constraint the class on a common base or interface.

In the CLR itself, the constraints (except for special ones, like the new-constraint) are stored rather simply: just a list of type identifiers, basically. So there's really no "room" for logical operations like you've specified... not without a revision to the CLR specification, or perhaps some really clever and ugly language-level tricks.

Josh Petrie
+2  A: 

You can extract the common functionality of TypeOne and TypeTwo into a base class or interface, and use that base class or interface as the constraint. Otherwise, how would the compiler know what it could do with T?

public interface IBelch
{
    void Belch();
}

public class Coke : IBelch
{
    public void Belch()
    {
    }
}

public class GatorAde : IBelch
{
    public void Belch()
    {
    }
}

public class SoftDrink<T>
    where T : IBelch
{
    public void DrinkFast(T drink)
    {
        drink.Belch();
    }
}
John Saunders
+3  A: 

You can't. The best you can do is use a common base class for the two, or a common interface implemented by both as a single type constraint.

David M
+7  A: 

Nope because that wouldn't make any sense. If you try to access a member function of "T", how can the compiler tell which base class to try and resolve members of?

You could try creating a common interface for TypeOne and TypeTwo and having the constraint specify that interface? What are you trying to accomplish, exactly?

Sapph
I was just trying to work around a particular issue without putting the two classes under a similar interfaces or base class.
Secret Agent Man
If you elaborate on the issue you're having, maybe we can help you figure out an alternate solution! :)
Sapph
Well, it was more of a curiosity than anything else. Basically, there are two methods in FormatXML, one that took TypeA, the other TypeB. An easy solution would be to have TypeA and TypeB implement IXMLFormattable or something similar.
Secret Agent Man
A: 

You could have TypeOne and TypeTwo inherit an interface and then do the following.

 public class SoftDrink<T>
    where T: IMyType
    {}
Khalid Abuhakmeh
+1  A: 

You could always do a runtime check against the type:

class TypeOne
{
    int _integer = 0;
}

class TypeTwo
{
    int _integer = 3;
}

class TypeThree
{
}

class SoftDrink<T>
{
    public SoftDrink()
    {
        if (typeof(T) != typeof(TypeOne) && typeof(T) != typeof(TypeTwo))
        {
            throw (new Exception("Sorry, but T must be TypeOne or TypeTwo"));
        }
    }
}

//this works:
SoftDrink<TypeOne> t1 = new SoftDrink<TypeThree>();    

//throws an exception:
SoftDrink<TypeThree> t3 = new SoftDrink<TypeThree>();
mlsteeves
Aggh, beat me to it by one minute; I was going to suggest the same thing. Of course, it's not true O-O, but it would work.
Loadmaster