Est-il possible en C # de convertir explicitement un objet de classe de base en une de ses classes dérivées? Je pense actuellement que je dois créer un constructeur pour mes classes dérivées qui accepte un objet de classe de base en tant que paramètre et copie les valeurs de propriété. Je n'aime pas vraiment cette idée, alors j'aimerais bien l'éviter si possible.
Cela ne semble pas fonctionner normalement (l'objet est instancié en tant que nouvelle base, la mémoire ne doit donc pas être allouée à des membres supplémentaires de la classe dérivée), mais C # semble me permettre de le faire:
class BaseClass
{
... some stuff ...
}
class DerivedClass : BaseClass
{
public bool MyDerivedProperty{ get; set; }
}
static void Main(string[] args)
{
BaseClass myBaseObject = new BaseClass();
DerivedClass myDerivedObject = myBaseObject as DerivedClass;
myDerivedObject.MyDerivedProperty = true;
}
Non, il n'y a pas de moyen intégré pour convertir une classe comme vous le dites. Le moyen le plus simple de procéder consiste à faire ce que vous avez suggéré: créer un constructeur DerivedClass(BaseClass)
. D’autres options permettraient essentiellement d’automatiser la copie des propriétés de la base vers l’instance dérivée, par exemple. en utilisant la réflexion.
Le code que vous avez publié à l'aide de as
sera compilé, comme vous l'avez sans doute déjà vu, mais émettra une exception de référence null lorsque vous l'exécuterez, car myBaseObject as DerivedClass
sera évalué à null
, puisque ce n'est pas une instance de DerivedClass
.
Ce n'est pas possible. mais vous pouvez utiliser un mappeur d'objets comme AutoMapper
Exemple:
class A
{
public int IntProp { get; set; }
}
class B
{
public int IntProp { get; set; }
public string StrProp { get; set; }
}
Dans global.asax ou au démarrage de l'application:
AutoMapper.Mapper.CreateMap<A, B>();
Usage:
var b = AutoMapper.Mapper.Map<B>(a);
Il est facilement configurable via une API fluide.
J'ai trouvé une solution à cela, sans dire que c'est la meilleure, mais elle me semble propre et ne nécessite aucune modification majeure de mon code. Mon code ressemblait au vôtre jusqu'à ce que je réalise que cela ne fonctionnait pas.
Ma classe de base
public class MyBaseClass
{
public string BaseProperty1 { get; set; }
public string BaseProperty2 { get; set; }
public string BaseProperty3 { get; set; }
public string BaseProperty4 { get; set; }
public string BaseProperty5 { get; set; }
}
Ma classe dérivée
public class MyDerivedClass : MyBaseClass
{
public string DerivedProperty1 { get; set; }
public string DerivedProperty2 { get; set; }
public string DerivedProperty3 { get; set; }
}
Méthode précédente pour obtenir une classe de base renseignée
public MyBaseClass GetPopulatedBaseClass()
{
var myBaseClass = new MyBaseClass();
myBaseClass.BaseProperty1 = "Something"
myBaseClass.BaseProperty2 = "Something else"
myBaseClass.BaseProperty3 = "Something more"
//etc...
return myBaseClass;
}
Avant, j'essayais cela, ce qui m'avait empêché de lancer une erreur
public MyDerivedClass GetPopulatedDerivedClass()
{
var newDerivedClass = (MyDerivedClass)GetPopulatedBaseClass();
newDerivedClass.UniqueProperty1 = "Some One";
newDerivedClass.UniqueProperty2 = "Some Thing";
newDerivedClass.UniqueProperty3 = "Some Thing Else";
return newDerivedClass;
}
J'ai changé mon code comme suit ci-dessous et cela semble fonctionner et a plus de sens maintenant:
ancien
public MyBaseClass GetPopulatedBaseClass()
{
var myBaseClass = new MyBaseClass();
myBaseClass.BaseProperty1 = "Something"
myBaseClass.BaseProperty2 = "Something else"
myBaseClass.BaseProperty3 = "Something more"
//etc...
return myBaseClass;
}
Nouvea
public void FillBaseClass(MyBaseClass myBaseClass)
{
myBaseClass.BaseProperty1 = "Something"
myBaseClass.BaseProperty2 = "Something else"
myBaseClass.BaseProperty3 = "Something more"
//etc...
}
ancien
public MyDerivedClass GetPopulatedDerivedClass()
{
var newDerivedClass = (MyDerivedClass)GetPopulatedBaseClass();
newDerivedClass.UniqueProperty1 = "Some One";
newDerivedClass.UniqueProperty2 = "Some Thing";
newDerivedClass.UniqueProperty3 = "Some Thing Else";
return newDerivedClass;
}
Nouvea
public MyDerivedClass GetPopulatedDerivedClass()
{
var newDerivedClass = new MyDerivedClass();
FillBaseClass(newDerivedClass);
newDerivedClass.UniqueProperty1 = "Some One";
newDerivedClass.UniqueProperty2 = "Some Thing";
newDerivedClass.UniqueProperty3 = "Some Thing Else";
return newDerivedClass;
}
Vous pouvez implémenter la conversion vous-même, mais je ne le recommanderais pas. Jetez un coup d'oeil au motif de décorateur si vous voulez le faire afin d'étendre les fonctionnalités d'un objet existant.
Non, il n'y a pas de conversion intégrée pour cela. Vous devrez créer un constructeur, comme vous l'avez mentionné, ou une autre méthode de conversion.
De plus, puisque BaseClass n'est pas une DerivedClass, myDerivedObject sera null et la dernière ligne ci-dessus lève une exception null ref.
Non ce n'est pas possible. La seule façon possible est
static void Main(string[] args)
{
BaseClass myBaseObject = new DerivedClass();
DerivedClass myDerivedObject = myBaseObject as DerivedClass;
myDerivedObject.MyDerivedProperty = true;
}