Domanda

Ho una classe generica

public MyClass<TContext, T> where TContext : DataContext

che agisce efficacemente su un'istanza di un'altra

public class MyOtherClass<T> : IEnumerable<T>

Voglio imporre che TContext abbia un Table<T>. C'è un modo pulito per far rispettare questo?

È stato utile?

Soluzione

Desideri verificare che TContext abbia un membro che è una tabella < T > ;? In tal caso, l'unico modo per farlo è definire un'interfaccia per questo contratto e modificare i tuoi vincoli generici

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

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

Modifica

Jason ha pubblicato un commento chiarificatore alla mia risposta. La tabella dei nomi non è statica, ma dipende dal tipo di T.

In tal caso, non è possibile forzare staticamente questo tramite vincoli generici. Il meglio che puoi fare è creare una classe adattatore che implementa IMyTable & Lt; & Gt; e fornisce un DataContext e un'istanza di 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; } }
}

Altri suggerimenti

Penso che JaredPar abbia avuto l'idea giusta la prima volta.

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

Voglio estendere il suo pensiero aggiungendo un'implementazione esplicita dell'interfaccia. Questo affronta l'osservazione di Jason sull'accesso alla proprietà della tabella tramite IMyTable. Il tipo deve essere coinvolto in qualche modo e se hai un IMyTable<T>, il tipo è coinvolto.

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

Ora è possibile farlo:

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

l'unico modo per applicarlo è se Table fosse in un'interfaccia e tu avessi assegnato un vincolo generico ... quindi qualcosa di simile

public class MyOtherClass<T> : IEnumerable<T>, IHasTable<T>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top