将基类转换为派生类

在C#中是否有可能将基类对象显式转换为其派生类之一? 目前认为我必须为我的派生类创build一个构造函数,接受基类对象作为参数并复制属性值。 我不太喜欢这个想法,所以如果可能的话,我想避免它。

这似乎不应该工作(对象被实例化为新的基地,所以内存不应该分配给派生类的额外成员),但C#似乎让我这样做:

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; } 

不,没有像你所说的转换class级的内置方式。 最简单的方法是按照你的build议做:创build一个DerivedClass(BaseClass)构造函数。 其他选项基本上会自动化从基础到派生实例的属性复制,例如使用reflection。

你使用的代码会编译,因为我相信你已经看到了,但是当你运行它的时候会抛出一个空的引用exception,因为myBaseObject as DerivedClass会计算为null ,因为它不是DerivedClass的一个实例。

这是不可能的。 但是可以使用像AutoMapper这样的Object Mapper

例:

 class A { public int IntProp { get; set; } } class B { public int IntProp { get; set; } public string StrProp { get; set; } } 

在global.asax或应用程序启动时:

 AutoMapper.Mapper.CreateMap<A, B>(); 

用法:

 var b = AutoMapper.Mapper.Map<B>(a); 

它可以通过stream畅的API轻松configuration。

我find了一个解决scheme,而不是说这是最好的,但它感觉干净,不需要我的代码的任何重大更改。 我的代码看起来很像你的,直到我意识到它没有工作。

我的基类

 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; } } 

我的派生类

 public class MyDerivedClass : MyBaseClass { public string DerivedProperty1 { get; set; } public string DerivedProperty2 { get; set; } public string DerivedProperty3 { get; set; } } 

先前的方法来获得填充的基类

 public MyBaseClass GetPopulatedBaseClass() { var myBaseClass = new MyBaseClass(); myBaseClass.BaseProperty1 = "Something" myBaseClass.BaseProperty2 = "Something else" myBaseClass.BaseProperty3 = "Something more" //etc... return myBaseClass; } 

在我尝试这个之前,这给了我一个无法抛出的错误

 public MyDerivedClass GetPopulatedDerivedClass() { var newDerivedClass = (MyDerivedClass)GetPopulatedBaseClass(); newDerivedClass.UniqueProperty1 = "Some One"; newDerivedClass.UniqueProperty2 = "Some Thing"; newDerivedClass.UniqueProperty3 = "Some Thing Else"; return newDerivedClass; } 

我改变了我的代码,如下图所示,它似乎工作,现在更有意义:

 public MyBaseClass GetPopulatedBaseClass() { var myBaseClass = new MyBaseClass(); myBaseClass.BaseProperty1 = "Something" myBaseClass.BaseProperty2 = "Something else" myBaseClass.BaseProperty3 = "Something more" //etc... return myBaseClass; } 

 public void FillBaseClass(MyBaseClass myBaseClass) { myBaseClass.BaseProperty1 = "Something" myBaseClass.BaseProperty2 = "Something else" myBaseClass.BaseProperty3 = "Something more" //etc... } 

 public MyDerivedClass GetPopulatedDerivedClass() { var newDerivedClass = (MyDerivedClass)GetPopulatedBaseClass(); newDerivedClass.UniqueProperty1 = "Some One"; newDerivedClass.UniqueProperty2 = "Some Thing"; newDerivedClass.UniqueProperty3 = "Some Thing Else"; return newDerivedClass; } 

 public MyDerivedClass GetPopulatedDerivedClass() { var newDerivedClass = new MyDerivedClass(); FillBaseClass(newDerivedClass); newDerivedClass.UniqueProperty1 = "Some One"; newDerivedClass.UniqueProperty2 = "Some Thing"; newDerivedClass.UniqueProperty3 = "Some Thing Else"; return newDerivedClass; } 

你可以自己实现转换,但我不会build议。 看看装饰模式,如果你想这样做,以扩大现有的对象的function。

不,这是不可能的。 唯一可能的方法是

 static void Main(string[] args) { BaseClass myBaseObject = new DerivedClass(); DerivedClass myDerivedObject = myBaseObject as DerivedClass; myDerivedObject.MyDerivedProperty = true; } 

不,没有内置的转换。 你需要像你提到的那样创build一个构造函数,或者其他一些转换方法。

另外,由于BaseClass不是DerivedClass,因此myDerivedObject将为null,并且上面的最后一行将抛出一个空ref参数。