C#等效于Java的GenericType <! - ? - >

时间:2014-01-15 16:16:31

标签: c# generics

我正在使用C#中的一些泛型。我有一个抽象的泛型类:

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

并且当其他类从基类继承时指定type参数。

我还试图为另一个需要存储其中一个基类的抽象类编写一些代码,但它不知道基类的参数(并且它不需要知道)。在Java中,我可以简单地写一下:

protected BaseClass<?> myBaseClass;

但是在C#中我坚持要给它一个类型参数。如果我将其声明为:

protected BaseClass<Foo> myBaseClass;

我无法为其分配BaseClass的任何参数化值。

是否有解决方案来实现{#1}}在C#中的效果?显然有一些方法可以重构我的代码以避免需要,例如参数化所有使用BaseClass<?>的类,但这不太理想。任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:2)

为了在C#中稍微匹配Java的行为,通常在继承层次结构中放置一个额外的非泛型接口。

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);
    }
}

然后在需要IBaseClass的地方使用BaseClass<?>

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

答案 1 :(得分:0)

如果您还不知道该类的泛型参数,那么使用此类型的类也需要是通用的。

答案 2 :(得分:0)

如果您在方法的参数声明中使用通配符,那么您需要使方法通用:

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

如果您将此作为变量类型声明使用,请使用var

var o = GetBaseClassOfSomeType();