将基类转换为派生类
在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参数。