2016-12-12 1 views
1

Also habe ich mich um eine Tonne von ähnlichen Fragen herumgetrieben, aber keiner von ihnen scheint das gleiche zu versuchen, was ich bin. Ich brauche einen Verweis auf eine Klasse, nicht auf eine Klasseninstanz.Erhalten Klassenreferenz von Klassentyp oder String

Ich versuche, eine Klassenreferenz für eine generische Typ-Funktion dynamisch zu erstellen. Meine Funktion ist wie folgt:

private void CleanupTable<T, U>(DbSet<T> dbSet, CleanupModel.Tables table, DbSet<U> lastDbSet, dynamic removedRec) where T : class where U : class 
{ 
    ParameterExpression tpe = Expression.Parameter(typeof(T)); 
    Expression idProp = Expression.Property(tpe, typeof(T).GetProperty(GetIdProperty(lastDbSet))); 
    Expression constIdProp = Expression.Constant(removedRec.GetType().GetProperty(GetIdProperty(lastDbSet)).GetValue(removedRec, null), typeof(int)); 
    Expression completeExpression = Expression.Equal(idProp, constIdProp); 

    Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(completeExpression, tpe); 
    List<T> removedRecs = dbSet.Where(expression).ToList(); 

    removedRecs.ForEach(rec => 
    { 
     DbSet nextSet = GetNextSet(dbSet); 

     //Here is where I'm trying to create a reference using nextSet 
     CleanupTable</*nextSetType reference*/, T>(nextSet, GetNextTable(dbSet), dbSet, rec); 

     dbSet.Remove(rec); 
     reportHelper.ReportSuccess(table, ReportHelper.ReportReasons.Linked, rec); 
    }); 
} 

Hier ist der Code für GetNextSet():

private DbSet GetNextSet(CleanupModel.Tables table) 
{ 
    switch (table) 
    { 
     case CleanupModel.Tables.Version: return context.Page; 
     //More cases 
     default: return null; 
    } 
} 

ich versucht habe, mit Dingen wie GetType() aber die generische akzeptieren keine Type. Ist das, was ich versuche, überhaupt möglich?

+2

Sie können [Makegenericmethod] (https: // msdn .microsoft.com/de-de/library/system.reflection.methodinfo.makegenericmethod (v = vs.110) .aspx). Überprüfen Sie das Beispiel am Ende –

+0

Ich bin mir nicht sicher, dass das tut, was ich brauche. Oder vielleicht verstehe ich es nicht gut genug. Könnten Sie das näher ausführen? –

+0

Warum funktioniert Typinferenz nicht? Was ist die Signatur von 'GetNextSet'? Was ist der Typ von 'nextSet'? – InBetween

Antwort

0

SOLUTION

So löste ich es dank der Hilfe von InBetween. Am Ende ließ ich CleanupTable() die Typen aus den Argumenten ableiten. Das Problem war ursprünglich, dass es den Typ nextSet nicht ableiten konnte, da es ein generischer DbSet Typ war und nicht implizit typisiert wurde. Ich löste dieses Problem, indem ich einfach die zugehörigen Werte auf Dynamik einstellte und CleanupTable() zur Laufzeit herausfinden konnte.

Hier ist der aktualisierte Code:

CleanupTable()

private void CleanupTable<T, U>(DbSet<T> dbSet, CleanupModel.Tables table, DbSet<U> lastDbSet, dynamic removedRec) where T : class where U : class 
{ 
    ParameterExpression tpe = Expression.Parameter(typeof(T)); 
    Expression idProp = Expression.Property(tpe, typeof(T).GetProperty(GetIdProperty(lastDbSet))); 
    Expression constIdProp = Expression.Constant(removedRec.GetType().GetProperty(GetIdProperty(lastDbSet)).GetValue(removedRec, null), typeof(int)); 
    Expression completeExpression = Expression.Equal(idProp, constIdProp); 

    Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(completeExpression, tpe); 
    List<T> removedRecs = dbSet.Where(expression).ToList(); 

    removedRecs.ForEach(rec => 
    { 
     dynamic nextSet = GetNextSet(table); 
     if (nextSet == null) 

     CleanupTable(nextSet, GetNextTable(table), dbSet, rec); 

     dbSet.Remove(rec); 
     reportHelper.ReportSuccess(table, ReportHelper.ReportReasons.Linked, rec); 
    }); 
} 

GetNextSet()

private dynamic GetNextSet(CleanupModel.Tables table) 
{ 
    switch (table) 
    { 
     case CleanupModel.Tables.Version: return context.Page; 
     //More cases 

     default: return null; 
    } 
} 
Verwandte Themen