C#相当于Java';s GenericType<&燃气轮机;

C#相当于Java';s GenericType<&燃气轮机;,c#,generics,C#,Generics,我正在使用C#中的一些泛型。我有一个抽象的泛型类: public abstract class BaseClass<T> where T : Foo { } 公共抽象类基类,其中T:Foo{} 当其他类从基类继承时,指定类型参数 我还试图为另一个需要存储这些基类之一的抽象类编写一些代码,但它不知道基类的参数(也不需要知道)。在Java中,我可以简单地编写: protected BaseClass<?> myBaseClass; 受保护的基类myBaseClass;

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

public abstract class BaseClass<T> where T : Foo { }
公共抽象类基类,其中T:Foo{}
当其他类从基类继承时,指定类型参数

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

protected BaseClass<?> myBaseClass;
受保护的基类myBaseClass;
但在C#中,它坚持我给它一个类型参数。如果我声明:

protected BaseClass<Foo> myBaseClass;
受保护的基类myBaseClass;
我无法将
BaseClass
的任何参数化值分配给它


在C#中,是否有一种方法可以实现基类的效果?显然,有一些方法可以重新构造代码以避免这种需要,比如参数化所有使用
BaseClass
的类,但这并不理想。任何帮助都将不胜感激

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

为了在某种程度上匹配Java在C#中的行为,通常在继承层次结构中添加一个额外的非泛型接口

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

如果在方法的参数声明中使用通配符,则需要将该方法设置为泛型:

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

定义不需要知道。在c#世界中,它确实需要知道。通过使用语法,您可以利用Java中的泛型类型实际上不是它自己的类型,而是语法糖这一事实。C#有更好的(更严格、可重新定义的)泛型类型,其副作用是您需要在所有声明中提供类型参数。出于某种原因,这个问题似乎在答案中吸引了很多反对票。除了海报所建议的解决方法之外,Java的基类功能无法实现。
var
与泛型有什么关系?@HighCore:不在变量声明中写入泛型类型。但也许我只是错过了OP提出的问题的一部分。我不记得了——IBaseClass.GetValue()实现中的强制转换真的是必需的吗?@SimonLindgren在大多数情况下,它可能不是必需的。但是如果
Foo
object
并且
T
是一个值类型,那么它是必需的。对于我正在做的事情来说,这似乎有点过分,但它似乎是结构最完善的解决方案。谢谢你的帮助!看起来这里有两个账户在积极地否决大多数答案。@T.J.Crowder我不知道它们是什么账户。我只注意到这里的所有答案(包括五个被删除的答案)要么没有投票,要么有两个或更多的反对票。
void printBaseClass<T>(BaseClass<T> o) where T : Foo {
  // ...
}
var o = GetBaseClassOfSomeType();