【问题标题】:Generics with Generic Parameters and Abstract class具有泛型参数和抽象类的泛型
【发布时间】:2011-04-05 17:13:17
【问题描述】:

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

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 会在绑定中抛出一个合适的。

【问题讨论】:

  • 虽然我没有在问题中提到 silverlight,但这是一个 silverlight 项目。我不确定这是否会限制解决方案。
  • 如果您尝试将 WCF RIA 服务的 TypeOf 编组为您的 POCO 类,则会限制解决方案,因为泛型不能作为 WCF 或 WCF RIA 服务公开(没有一些主要的解决方法)。
  • 您是否使用了有关 FirstClass 的任何类型特定信息?如果不是,我倾向于在这些情况下做的是让 FirstClass 匹配某个 IGenericFirstClass 接口,然后将约束指定为 IGenericFirstClass。它隐藏了 U 型依赖。
  • UT 是不同的类型吗?
  • @Stefan - 我编辑了代码以试图澄清

标签: c# silverlight generics


【解决方案1】:

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

interface IFirstClass {...}

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

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

【讨论】:

  • 请查看我的编辑。我还没有遇到需要强制转换为基类的问题。
【解决方案2】:

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

【讨论】:

  • 我是这么想的,但如果我们没有希望,我们还有什么?
  • @cadrell0: careers.stackoverflow.com ;) 不过,说真的,不要忘记接受这些答案之一。这些几乎是您唯一的选择。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    这实际上是对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 类型,您将收到编译器错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多