3

我有一个通用类

public MyClass<TContext, T> where TContext : DataContext

有效地作用于另一个实例

public class MyOtherClass<T> : IEnumerable<T>

我想强制TContext执行Table<T>. 有没有一种干净的方法来执行此操作?

4

3 回答 3

6

您是否要验证 TContext 是否有一个 Table<T> 成员?如果是这样,唯一的方法是为此合约定义一个接口并更改您的通用约束

interface IMyTable<T> {
  Table<T> Table;
}

public MyClass<TContext,T> where TContext : DataContext,IMyTable<T>

编辑

杰森对我的回答发表了澄清评论。名称 Table 不是静态的,而是取决于 T 的类型。

如果是这种情况,那么就无法通过通用约束静态地强制执行此操作。您可以做的最好的事情是创建一个实现 IMyTable<> 并提供 DataContext 和 Table 实例的适配器类。

interface IMyTable2<T> {
  DataContext DataContext {get; }
  Table<T> Table {get; }
}

class MyAdapter: IMyTable2<T> {
  private MyOtherClass<T> _other;
  public DataContext DataContext { get { return _other.DataContext } }
  public Table<T> Table { get { return _other.TableWithDifferentName; } }
}
于 2009-01-23T18:23:10.467 回答
1

我认为 JaredPar 第一次提出了正确的想法。

interface IMyTable<T>
{
  Table<T> TheTable {get;}
}

public class MyClass<TContext,T> where
  TContext : DataContext,IMyTable<T>
{
  //silly implementation provided to support the later example:
  public TContext Source {get;set;}

  public List<T> GetThem()
  {
    IMyTable<T> x = Source as IMyTable<T>;
    return x.TheTable.ToList(); 
  }
}

我想通过添加显式接口实现来扩展他的想法。这解决了 Jason 关于通过 IMyTable 访问表属性的评论。必须以某种方式涉及类型,如果您有IMyTable<T>,则涉及类型。

public partial class MyDataContext:IMyTable<Customer>, IMyTable<Order>
{
  Table<Customer> IMyTable<Customer>.TheTable
  { get{ return this.GetTable<Customer>(); } }

  Table<Order> IMyTable<Order>.TheTable
  { get{ return this.GetTable<Order>(); } }  
}

现在可以这样做:

var z = new MyClass<MyDataContext, Customer>();
z.Source = new MyDataContext();
List<Customer> result = z.GetThem();
于 2009-01-23T20:14:18.090 回答
-1

强制执行它的唯一方法是,如果 Table 位于接口中,并且您分配了通用约束......所以类似

public class MyOtherClass<T> : IEnumerable<T>, IHasTable<T>
于 2009-01-23T18:23:50.887 回答