6

我正在研究一个小型类库,它自然涉及使用泛型来完成这项任务。但是有一点我对泛型不太了解:为什么我需要使用泛型类型参数,然后将类型参数约束到特定的基类或接口。

这是我的意思的一个例子:

public class MyGenericClass<T> where T : SomeBaseClass
{
    private T data;
}

这是没有泛型的实现

public class MyClass
{
    private SomeBaseClass data;
}

这两个定义是否相同(如果是,那么我在这里看不到使用泛型的好处)?

如果不是,我们在这里使用泛型有什么好处?

4

5 回答 5

7

与仿制药的几乎所有用途一样,消费者受益。约束类型为您提供与通过强输入参数获得的相同优势(或者您可以执行其他操作,例如确保有一个公共无参数构造函数或确保它是值类型或引用类型),同时仍保留泛型的优点你的类或函数的消费者。

例如,使用泛型还可以让您获得指定的实际类型,如果它具有任何特定值的话。

这个例子有点做作,但看看这个:

public class BaseClass
{
    public void FunctionYouNeed();
}

public class Derived : BaseClass
{
    public void OtherFunction();
}

public class MyGenericClass<T> where T: BaseClass
{
    public MyGenericClass(T wrappedValue)
    {
        WrappedValue = wrappedValue;
    }

    public T WrappedValue { get; set; }

    public void Foo()
    {
        WrappedValue.FunctionYouNeed();
    }
}

...

var MyGenericClass bar = new MyGenericClass<Derived>(new Derived());

bar.Foo();

bar.WrappedValue.OtherFunction();
于 2012-04-30T13:25:11.530 回答
1

区别在于前者将新类定义为特定类型;后者只是简单地定义了一个具有该类型字段的普通类。

于 2012-04-30T13:28:11.367 回答
1

这都是关于类型安全的。使用泛型,您可以返回一个具体类型 (T),而不是一些定义泛型类中所需 API 的基类型。因此,您的方法的调用者不必将结果转换为具体类型(这是一个容易出错的操作)。

于 2012-04-30T13:28:52.167 回答
1

主要区别在于用法。在第一种情况下,用法可以有:

MyGenericClass<SomeDerivedClass> Variable
Variable.data.SomeDerivedProperty = X

因此,当您使用该类时,您仍然可以访问 SomeDerivedClass 中的任何内容,而无需回溯到它。

第二个示例不允许这样做。

MyClass.data = SomeDerivedClassInstance
MyClass.data.SomeDerivedProperty = X //Compile Error
((SomeDerivedClass)MyClass.data).SomeDerivedProperty = X //Ewwwww

您将不得不转换回 SomeDerivedClass (这是不安全的)以使用特定于派生类的东西。

于 2012-04-30T13:29:45.940 回答
1

我认为除了通用版本限制您的Class之外没有很大的区别,而第二个只是对班级成员的限制。如果你在你的第一个类中添加了更多的成员和方法,你就会有同样的约束。

于 2012-04-30T13:29:56.990 回答