Generisches Durchsetzung
-
19-08-2019 - |
Frage
Ich habe eine generische Klasse
public MyClass<TContext, T> where TContext : DataContext
, die effektiv wirkt auf eine Instanz einer anderen
public class MyOtherClass<T> : IEnumerable<T>
Ich will erzwingen, dass der TContext
eine Table<T>
hat. Gibt es eine saubere Art und Weise, dies zu erzwingen?
Lösung
Wollen Sie, um sicherzustellen, dass TContext ein Mitglied hat, das ist eine Tabelle
interface IMyTable<T> {
Table<T> Table;
}
public MyClass<TContext,T> where TContext : DataContext,IMyTable<T>
Bearbeiten
Jason schrieb einen Kommentar zu klären meine Antwort. Der Name der Tabelle ist nicht statisch, es hängt stattdessen von der Art von T.
Wenn das der Fall ist, dann gibt es keine Möglichkeit, dies durch generische Einschränkungen statisch zu erzwingen. Das Beste, was Sie tun können, ist eine Adapterklasse zu schaffen, die implementiert IMyTable <> und stellt eine Datacontext und eine Tabelle Instanz.
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; } }
}
Andere Tipps
Ich denke, JaredPar die richtige Idee zum ersten Mal hatte sich um.
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();
}
}
Ich mag seine Gedanken erweitern, indem eine explizite Schnittstellenimplementierung hinzufügen. Diese befasst sich Jason Bemerkung über die Tabelleneigenschaft durch IMyTable erreichbar. Der Typ muss irgendwie beteiligt sein, und wenn Sie eine IMyTable<T>
haben, die Art beteiligt ist.
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>(); } }
}
Nun ist es möglich, dies zu tun:
var z = new MyClass<MyDataContext, Customer>();
z.Source = new MyDataContext();
List<Customer> result = z.GetThem();
den einzigen Weg, es zu erzwingen, wenn Tabelle in einer Schnittstelle war, und Sie zugewiesen eine generische Einschränkung ... so etwas wie
public class MyOtherClass<T> : IEnumerable<T>, IHasTable<T>