具有泛型参数的泛型和抽象类

本文关键字:泛型 抽象类 参数 | 更新日期: 2023-09-27 17:49:20

我有两个通用基类。第二个泛型类对第一个类的形参有一个约束。

abstract class FirstClass<T> {...}
abstract class SecondClass<U> where U : FirstClass {...}

这不起作用,因为没有定义FirstClass。所以我需要这样做

abstract class FirstClass<T> {...}
abstract class SecondClass<U, T> where U : FirstClass<T> {...}

工作。然而,这使得实现这些抽象类变得丑陋。

class SomeClass {...}
class MyFirstClass : FirstClass<SomeClass> {...}
class MySecondClass : SecondClass<MyFirstClass, SomeClass> {...}

这对我来说似乎是多余的,因为我指定了两次SomeClass。是否有一种方法可以声明它,使FirstClass中的T自动成为SecondClass的U。我真正想要的是。

class SomeClass {...}
class MyFirstClass : FirstClass<SomeClass> {...}
class MySecondClass : SecondClass<MyFirstClass> {...}

虽然我怀疑这种确切的场景是可能的,但是否有一个更清晰的方法来做我想做的事情?

编辑

一些人建议创建IFirstClass接口。但我的定义更接近于此。

class FirstClass<T>
{
    public T MyObj { get; set; }
}
class SecondClass<U, T> where U : FirstClass<T>
{
    U MyFirstClass { get; set; }
}

使用接口我不能访问MyFirstClass。MyObj来自SecondClass。虽然我可以创建一个object T MyObj { get; set; } on IFirstClass, then use new来隐藏它,但如果我这样做,silverlight会在绑定中抛出一个fit。

具有泛型参数的泛型和抽象类

根据我的经验,为泛型类创建非泛型接口是最容易的。它还解决了在不知道泛型类型的情况下需要强制转换为基类的问题。

interface IFirstClass {...}
abstract class FirstClass<T> : IFirstClass {...}
abstract class SecondClass<T> where T : IFirstClass {...}

如果您实际上正在使用FirstClass的泛型类型参数(从您的编辑中,听起来像是您),那么不,不幸的是,您正在寻找的是不可能的。编译器不区分相关和不相关的类型参数

创建一个FirstClass实现的接口。然后,您可以将SecondClass约束到接口。

这实际上是一个有两个通用参数的接口的答案,自动解决一个被标记为重复的问题

你可以用一个特定的Id类型声明一堆接口。这不是一个完美的解决方案,但是简化了实体类的声明。

public interface IIntPersistentEntityService<TPersistentEntity>
        : IPersistentEntityService<TPersistentEntity, int>
    where TPersistentEntity : IPersistentEntity<int>
{
}
public interface IStringPersistentEntityService<TPersistentEntity>
        : IPersistentEntityService<TPersistentEntity, string>
    where TPersistentEntity : IPersistentEntity<string>
{
}

那么User类可以这样声明:

public class UserService : IIntPersistentEntityService<User>
{
    public User Get(int id)
    {
        throw new NotImplementedException();
    }
}

如果你没有匹配的Id类型,你将得到一个编译错误。