具有泛型参数的泛型和抽象类
本文关键字:泛型 抽象类 参数 | 更新日期: 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类型,你将得到一个编译错误。