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

时间:2011-04-05 17:13:17

标签: c# silverlight generics

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

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

使用接口我无法从SecondClass访问MyFirstClass.MyObj。虽然我可以在IFirstClass上创建object T MyObj { get; set; },然后使用new隐藏它,如果我这样做,silverlight会在绑定中抛出一个契合。

4 个答案:

答案 0 :(得分:11)

根据我的经验,最简单的方法是创建泛型类的非泛型接口。当你需要在不知道泛型类型的情况下强制转换为基类时,它也解决了这个问题。

interface IFirstClass {...}

abstract class FirstClass<T> : IFirstClass {...}

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

答案 1 :(得分:4)

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

答案 2 :(得分:2)

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

答案 3 :(得分:0)

这实际上是对Interface with two generic parameters, solve one automatically的回答,它被标记为该问题的重复。

您可以声明一堆具有特定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类型,则会出现编译器错误。