2017-01-05 2 views
1

Ich habe die folgenden Klassen:Pass Allgemein Typ up Vererbungsbaum

abstract class Foo<T>
abstract class BaseClass : Foo<BaseClass>
class DerivedOne : BaseClass
class DerivedTwo : BaseClass

diese Struktur verwenden, werden alle Klasse, die von Foo<BaseClass> von BaseClass erben abzuleiten. Ich mag die allgemeine Art von T verschiedenen in jeder abgeleiteten Klasse

Zum Beispiel einstellen zu können, in DerivedOne ich die Klasse will Foo<DerivedOne> sein, aber in DerivedTwo Ich mag die Klasse von Foo<DerivedTwo> abzuleiten.

Gibt es eine Möglichkeit, den Vererbungsbaum die gattungs bis passieren?

Ich habe versucht, so etwas wie dies zu tun (was nicht funktioniert).

abstract class Foo<T>
abstract class BaseClass<T> : Foo<T>
class DerivedOne : BaseClass<DerivedOne>
class DerivedTwo : BaseClass<DerivedTwo>

Edit: geändert generische Typen zu zeigen, dass sie in sich als generische Typen sind vorbei

Edit # 2: Hier ist ein Beispiel für den Code der tatsächlichen ist Klassen, die ich verwende:

public abstract class DBObject<T> 
    where T : DBObject<T>, new() 
{ 
    //the generic type is for this method, so I can create an object from a database query 
    public static T Create(DataRow dataRow) 
    { 
     Type T = MethodBase.GetCurrentMethod().DeclaringType; 
     T obj = new T(); 

     foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)) 
     { 
      if (dataRow.Table.Columns.Contains(field.Name)) 
      { 
       Object safeObj = Convert.ChangeType(dataRow[field.Name].ToString(), field.FieldType); 
       field.SetValue(obj, safeObj); 
      } 

     } 

     foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)) 
     { 
      Console.WriteLine(field.Name + "=" + field.GetValue(obj)); 
      //propInfo.SetValue(obj, value, null); 
     } 
     return obj;    
    } 
} 

public abstract class Contact<T> : DBObject<T> 
    where T : Contact<T> 
{ 
    //field and methods ommitted... 
} 

public class Person : Contact<Person> 
{ 
    //fields and methods ommitted... 
} 

public class Company : Contact<Company> 
{ 
    //fields and methods ommitted... 
} 

Die Klassen können dann in einer solchen Weise verwendet werden:

Person person = Person.Create(/* DataRow from a query result */); 
+0

Das Beispiel, das Sie gaben funktioniert perfekt, es ist wahrscheinlich etwas anderes, warum sagen Sie, es funktioniert nicht –

+1

Vielleicht möchten Sie abstrakte Klasse BaseClass : Foo wo T: Bar? –

+0

@Nobody ich die folgenden Fehler 'Der Typ‚T‘bekommen kann nicht als Typ-Parameter‚T‘in dem generischen Typ oder Methode‚Foo ‘verwendet werden. Es gibt keine Boxkonvertierung oder Typparameterkonvertierung von 'T' nach 'Foo '. 'Und '' T 'muss ein nicht abstrakter Typ mit einem öffentlichen parameterlosen Konstruktor sein, um ihn als Parameter' T 'im generischen Typ zu verwenden Art oder Methode ‚Foo ‘ ' – yitzih

Antwort

1

ich Ihren Code zu kompilieren, wenn Sie die new() Einschränkung Contact<T> hinzufügen:

public abstract class Contact<T> : DBObject<T> 
    where T : Contact<T>, new() 
{ 
    //field and methods ommitted... 
} 

Dieses seit generic constraints aren't inherited notwendig ist.