C#中与Java的GenericType<?>相当的是什么?

7

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

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

当其他类继承基类时,可以指定类型参数。

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

protected BaseClass<?> myBaseClass;

但在C#中,它要求我提供一个类型参数。如果我声明为:

protected BaseClass<Foo> myBaseClass;

我不能将任何带参数的BaseClass值分配给它。

在C#中有没有绕过来实现BaseClass<?>的效果的方法?显然,有一些方法可以重新组织我的代码以避免需要,例如对使用BaseClass的所有类进行参数化,但这不是最理想的方法。任何帮助都将不胜感激!


定义不需要知道。在C#世界中,它需要知道。 - rerun
1
通过使用 <?> 语法,您可以利用 Java 中通用类型实际上并不是自己的类型,而只是语法糖的事实。C# 有更好(更严格、可重用)的通用类型,其副作用是您需要在所有声明中提供类型参数。 - Simon Lindgren
这个问题似乎因为某些原因在回答中吸引了很多负评。除了提问者提出的变通方法之外,没有其他方式可以实现Java的BaseClass<?>功能。 - Sean
3个回答

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

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

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

我不记得了 - IBaseClass.GetValue() 实现中的转换是否真的必要? - Simon Lindgren
1
在大多数情况下,可能不需要。但是如果Fooobject,而T是值类型,则确实需要。 - Daniel A.A. Pelsmaeker
这似乎有点过度设计,但它似乎是最结构化的解决方案。感谢您的帮助! - thomas88wp
看起来有两个账户在积极地对这里的大多数答案进行负面评价。 - Daniel A.A. Pelsmaeker
1
@T.J.Crowder 我不知道它们是哪些账户。我只注意到这里的所有答案(包括五个已删除的答案)要么没有投票,要么有两个或更多的反对票。 - Daniel A.A. Pelsmaeker
@Virtlink:糟糕!*(看起来有点懊恼)* 很抱歉,昨天状态不佳。 - T.J. Crowder

0
如果您在方法的参数声明中使用通配符,则需要将该方法泛型化:
void printBaseClass<T>(BaseClass<T> o) where T : Foo {
  // ...
}

如果您将其用作变量类型声明,请使用var
var o = GetBaseClassOfSomeType();

var 与泛型有什么关系? - Federico Berasategui
@HighCore:在变量声明中没有写入泛型类型。但也许我只是错过了提问者所问问题的某个部分。 - Laurent LA RIZZA

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接