将基类转换为派生类

有没有可能在 C # 中显式地将一个基类对象转换为它的一个派生类?当前的想法是,我必须为我的派生类创建一个构造函数,该构造函数接受基类对象作为参数,并复制属性值。我真的不喜欢这个主意,所以如果可能的话我想避免它。

这看起来似乎不应该工作(对象被实例化为新的基类,所以内存不应该被分配给派生类的额外成员) ,但 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;
}
270514 次浏览

不,没有内置的方法可以像你说的那样转换类。最简单的方法是按照您的建议: 创建一个 DerivedClass(BaseClass)构造函数。其他选项基本上可以自动将属性从基实例复制到派生实例,例如使用反射。

您使用 as发布的代码将进行编译,我相信您已经看到了这一点,但是当您运行它时将抛出一个空引用异常,因为 myBaseObject as DerivedClass将计算为 null,因为它不是 DerivedClass的实例。

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

此外,由于 BaseClass 不是一个衍生类,my 习对象将为 null,并且上面的最后一行将抛出一个 null ref 异常。

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

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


myDerivedObject.MyDerivedProperty = true;
}

您可以自己实现转换,但我不建议这样做。如果您想要扩展现有对象的功能,请查看 修饰模式

这是不可能的。但是您可以使用类似于 自动绘图软件的对象映射器

剪辑

我想推荐一个更简单的对象映射器: TinyMapper。AutoMapper 现在使用起来非常复杂。我已经不用了。TinyMapper 涵盖了大多数用例,而且非常简单,而且速度非常快。

例如:

//In app startup
TinyMapper.Bind<Person, PersonDto>();


//Usage
var personDto = TinyMapper.Map<PersonDto>(person);

例如自动映射器(我认为是较老的版本) ,对于那些仍然想使用它的人来说:

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

它可以通过一个流畅的 API 进行配置。

我已经找到了一个解决方案,不是说它是最好的解决方案,但我觉得它很干净,不需要对我的代码进行任何重大更改。我的代码看起来和你的很像,直到我意识到它不起作用。

我的基类

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