Pergunta

Eu tenho uma classe genérica

public MyClass<TContext, T> where TContext : DataContext

que efetivamente atua sobre uma instância de outra

public class MyOtherClass<T> : IEnumerable<T>

Eu quero impor que o TContext tem uma Table<T>. Existe uma maneira limpa para fazer cumprir isso?

Foi útil?

Solução

Você está querendo verificar se TContext tem um membro que é um Table ? Se assim for, a única maneira de fazer isso é definir uma interface para o presente contrato e alterar suas limitações genéricas

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

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

Editar

Jason postou um comentário esclarecer a minha resposta. Nome da tabela não é estático, em vez depende do tipo de T.

Se for esse o caso, então não há nenhuma maneira de impor estaticamente isso através de restrições genéricas. O melhor que você pode fazer é criar uma classe do adaptador que implementa IMyTable <> e fornece um DataContext e uma instância da tabela.

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

Outras dicas

Eu acho JaredPar teve a idéia certa na primeira vez.

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

Eu quero estender seu pensamento através da adição de uma implementação de interface explícita. Isso resolve o comentário de Jason sobre como acessar a propriedade tabela através IMyTable. O tipo deve estar envolvido de alguma forma, e se você tem um IMyTable<T>, o tipo está envolvido.

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

Agora é possível fazer isso:

var z = new MyClass<MyDataContext, Customer>();
z.Source = new MyDataContext();
List<Customer> result = z.GetThem();

a única maneira de aplicá-la é se mesa estava em uma interface, e você atribuiu uma restrição genérica ... então algo como

public class MyOtherClass<T> : IEnumerable<T>, IHasTable<T>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top