简体   繁体   English

Java的GenericType的C#等效项<?>

[英]C# Equivalent of Java's GenericType<?>

I'm working with some generics in C#. 我正在使用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. 当其他类从基类继承时,指定type参数。

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: 在Java中,我可以简单地写:

protected BaseClass<?> myBaseClass;

But in C# it insists I give it a type parameter. 但是在C#中,它坚持要给我一个类型参数。 If I declare it as: 如果我声明为:

protected BaseClass<Foo> myBaseClass;

I cannot assign any parametrized values of BaseClass to it. 我不能为其分配任何BaseClass参数化的值。

Is there a work around to achieve the effect of BaseClass<?> in C#? 是否可以解决C#中BaseClass<?>问题? 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. 显然,有一些方法可以重组我的代码来避免这种需要,例如,对所有使用BaseClass的类进行参数BaseClass ,但这并不理想。 Any help would be appreciated! 任何帮助,将不胜感激!

To match Java's behavior somewhat in C#, it is common to put an additional non-generic interface in the inheritance hierarchy. 为了在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);
    }
}

And then use IBaseClass where you need BaseClass<?> : 然后在需要BaseClass<?>地方使用IBaseClass

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

如果您还不知道该类的通用参数,则使用该类型的类也将需要通用。

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

var o = GetBaseClassOfSomeType();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM