thomas8wp
thomas8wp

Reputation: 2411

C# Equivalent of Java's GenericType<?>

I'm working with some generics in C#. I have an abstract generic class:

public abstract class BaseClass<T> where T : Foo { }

and the type parameter is specified when other classes inherit from the base class.

I'm also trying to write some code for another abstract class that needs to store one of these base classes, but it won't know the parameter of the base class (and it doesn't need to know). In Java I could simple write:

protected BaseClass<?> myBaseClass;

But in C# it insists I give it a type parameter. If I declare it as:

protected BaseClass<Foo> myBaseClass;

I cannot assign any parametrized values of BaseClass to it.

Is there a work around to achieve the effect of BaseClass<?> in C#? Obviously there are ways to restructure my code to avoid the need, such as parameterizing all of the classes that use BaseClass as well, but this would be less than ideal. Any help would be appreciated!

Upvotes: 7

Views: 1515

Answers (3)

Laurent LA RIZZA
Laurent LA RIZZA

Reputation: 2965

If you're using the wildcard in a parameter declaration to a method, then you'll need to make the method generic:

void printBaseClass<T>(BaseClass<T> o) where T : Foo {
  // ...
}

If you're using this as a variable type declaration, just use var.

var o = GetBaseClassOfSomeType();

Upvotes: 0

Daniel A.A. Pelsmaeker
Daniel A.A. Pelsmaeker

Reputation: 50326

To match Java's behavior somewhat in C#, it is common to put an additional non-generic interface in the inheritance hierarchy.

public interface IBaseClass
{
    Foo GetValue();

    void SetValue(Foo value);
}

public abstract class BaseClass<T> : IBaseClass
    where T : Foo
{
    public T GetValue<T>()
    { /* ... */ }

    public void SetValue<T>(T value)
    { /* ... */ }

    Foo IBaseClass.GetValue()    // Explicit interface method implementation
    {
        return (Foo)GetValue<T>();
    }

    void IBaseClass.SetValue(Foo value)    // Explicit interface method impl.
    {
        SetValue<T>((T)value);
    }
}

And then use IBaseClass where you need BaseClass<?>:

IBaseClass myClass;
Foo f = myClass.GetValue();

Upvotes: 2

Servy
Servy

Reputation: 203830

The classes using this type will also need to be generic, if you don't yet know the generic argument of that class yet.

Upvotes: 0

Related Questions