2016-04-11 14 views
2

ich eine Variable objDataModel vom Typ haben UDataModel die sich von AbstractDataModeltypisieren mit Typ/string Name der Klasse

public class AbstractDataModel 
{ 
    internal string SomeName { get; set; } 
} 
public class UDataModel: AbstractDataModel 
{ 

} 

public class FDataModel: AbstractDataModel 
{ 

} 


public class UCommandProcessor : AbstractCommandProcessor<UDataModel> 
{ 

} 
public class FCommandProcessor : AbstractCommandProcessor<FDataModel> 
{ 

} 
public abstract class AbstractCommandProcessor<TDataModel> :SomeInterface<TDataModel> 
    where TDataModel: AbstractDataModel 
{ 

} 

erbt Ich habe Variable vom Typ von UDataModelType heißt var tDataModelType= typeOf(UDataModel) verwendet, die ich in der Lage bin sein Objekt zu erstellen.

var tDataModel = (AbstractDataModel)Activator.CreateInstance(tDataModelType); 

Ich habe Variable vom Typ UCommandProcessor dh var processorType= typeOf(UCommandProcessor) ich in der Lage bin Aufgabe

var processor = Activator.CreateInstance(processorType); 

zu schaffen, aber ich bin nicht in der Lage es in UCommandProcessor typisieren Als ich versuchte,

var processor = (AbstractCommandProcessor<AbstractDataModel>)Activator.CreateInstance(processorType); 

Ich bekomme eine Ausnahme von

Das Objekt des Typs 'ABC.Domain.UCommandProcessor' konnte nicht in den Typ 'ABC.Common.Contract.AbstractCommandProcessor`1 [ABC.Common.Contract.AbstractDataModel]' umgewandelt werden.

Gibt es eine Methode wie

var processor = (AbstractCommandProcessor<typeOf(tDataModel)>)Activator.CreateInstance(processorType); 

Auch ich wie

var processor = (AbstractCommandProcessor<typeOf(tDataModel)>)Activator.CreateInstance(processorType); 
+1

Soll 'UserDataModel'' UDataModel' sein oder sind das zwei verschiedene Typen? – 31eee384

+0

aktualisierte Frage, Sorry für Verwirrung verursacht –

Antwort

2

Die Besetzung kann nicht funktionieren, tun kann nicht, wenn Sie AbstractCommandProcessor<AbstractDataModel> werfen Sie im Grunde Kovarianz benötigt werden, was nur für Schnittstellen und Delegaten unterstützt. In dieser Zeile:

(AbstractCommandProcessor<AbstractDataModel>)Activator.CreateInstance(processorType); 

Die Besetzung könnte genauso gut ein AbstractCommandProcessor<FDataModel> sein, die eindeutig nicht gültig ist. Ich würde vorschlagen, eine abstrakte Klasse machen AbstractCommandProcessor, aus denen die generische Version stammt, dann können Sie nur auf die nicht-generische Version werfen:

public abstract class AbstractCommandProcessor {} 

public class AbstractCommandProcessor<T> : AbstractCommandProcessor, SomeInterface<T> 
              where T: AbstractDataModel 

... 
var processor = (AbstractCommandProcessor)Activator.CreateInstance(processorType); 

Edit: Wenn Sie nicht wirklich Klassen benötigen, könnten Sie machen es arbeitet mit Schnittstellen und Kovarianz:

public interface AbstractDataModel { } 
public class UDataModel : AbstractDataModel { } 
public class FDataModel : AbstractDataModel { } 


public class UCommandProcessor : AbstractCommandProcessor<UDataModel> { } 
public class FCommandProcessor : AbstractCommandProcessor<UDataModel> { } 
public interface AbstractCommandProcessor<out TDataModel> : SomeInterface<TDataModel> 
where TDataModel : AbstractDataModel 
{ } 

public interface SomeInterface<out TDataModel> where TDataModel : AbstractDataModel { } 

... 

var processor = 
    (AbstractCommandProcessor<AbstractDataModel>)Activator.CreateInstance(processorType); 

Dies wegen Kovarianz arbeiten (das out Schlüsselwort, das bedeutet, dass Sie etwas mehr abgeleitet sein als durch die generische Einschränkung verwenden können).

+0

Vielen Dank Alexander. Ich verwende die erste von Ihnen vorgeschlagene Option. –

+0

Ich habe eine Methode öffentliche void LoadModel (T-Modell) innerhalb der Klasse öffentliche Klasse AbstractCommandProcessor , Aber nach der Typumwandlung kann ich diese Methode als AbstractCommandProcessor nicht diese Methode aufrufen. :( –

+0

@RoshanGhangare Warum nicht implementieren public abstract void LoadModel (AbstractDataModel Modell); 'in der abstrakten Basisklasse? In der abgeleiteten Klasse haben Sie:' öffentliche Überschreibung void LoadModel (AbstractDataModel Modell) 'und in der Methode können Sie Wirf das Modell auf T: 'LoadModel (Modell des abstraktenDatenmodells) {T abgeleitetenModell = (T) -Modell; ....}' –

Verwandte Themen