我通过派生来扩展现有的.NET框架类。如何将基类型的对象转换为派生类型?
public class Results { //Framework methods }
public class MyResults : Results { //Nothing here }
//I call the framework method
public static MyResults GetResults()
{
Results results = new Results();
//Results results = new MyResults(); //tried this as well.
results = CallFrameworkMethod();
return (MyResults)results; //Throws runtime exception
}
我理解这种情况发生在我尝试将基类型转换为派生类型时,如果派生类型具有其他属性,则不会分配内存。当我添加其他属性时,我不在乎它们是否被初始化为null。
如果不进行手动复制,我该怎么做?
答案 0 :(得分:11)
你做不到。如果results
未引用MyResults
(例如,如果CallFrameworkMethod
返回基本Results
实例),则转换将不会如此:您需要根据现有的非MyResults
创建新的MyResults
。转换是关于更改引用的编译时类型,而不是更改引用对象的具体类型。
您可以使用Reflection或AutoMapper等工具来帮助初始化新的MyResults
对象 - 但必须有一个新的MyResults
对象,因为您无法告诉基础{{1 object成为Results
对象。
答案 1 :(得分:1)
怎么样:
...
MyResults results = new MyResults();
...
您可能还需要在MyResults
类中创建一个COnstructor:
public class MyResults : Results
{
public MyResults() : base() {}
}
击> <击> 撞击> 究竟什么意思“什么都没有”?
编辑
results = (CallFrameworkMethod() as MyResults);
它不会抛出异常,但如果它对你有用 - 这取决于你想要做的事情......
答案 2 :(得分:1)
不,您无法避免将内容复制到派生类型的实例中。好吧,如果您可以将CallFrameworkMethod更改为通用方法,并且MyResults具有零参数构造函数,则CallFrameworkMethod可以直接创建派生类型的新实例,然后仅使用父类型的成员。
但是你可能不得不最终复制到一个新对象。请记住,这个复制代码当然可以在另一个方法中重用,您无需在任何需要的地方重写它。
答案 3 :(得分:1)
如前面的答案所述,您需要实例化MyResults的新实例,然后从Results对象复制属性。你问了什么是“复制构造函数” - 它只是一个构造函数,它接受一个对象并使用它来填充正在构造的对象。例如:
public class Results
{
public string SampleProperty1 { get; set; }
public string SampleProperty2 { get; set; }
}
public class MyResults : Results
{
public MyResults(Results results)
{
SampleProperty1 = results.SampleProperty1;
SampleProperty2 = results.SampleProperty2;
}
}
复制构造函数通常比使用这样的代码更方便,可读和可重用:
MyResults myResults = new MyResults
{
SampleProperty1 = results.SampleProperty1,
SampleProperty2 = results.SampleProperty2
};
如果有很多属性和/或您对该类进行了大量更改,则可以使用反射(例如C# Using Reflection to copy base class properties)或AutoMapper(http://automapper.codeplex.com等工具)来复制属性。但通常这可能是矫枉过正的。
答案 4 :(得分:0)
Results results = new MyResults();
...
return (MyResults)results;
应该有效。如果没有,那么问题就在某处。
答案 5 :(得分:0)
要将对象向下转换为其派生类,对象必须出生在其派生类中。 例如: 我有一个简单的类叫做 Shape 这是Shape类的代码
public class Shape{
public void draw(){}
}
然后我还有一个名为 Circle 的类,如下所示:
public class Circle:Shape{
public void drawCircle(){}
}
现在如果我创建一个像超级类的对象
Shape noShape = new Shape();
如果尝试像这样将这个 noShape
对象向下转换为 Circle
对象
Circle circle = (Circle) noShape;
它会产生一个异常。这是因为 circle
从未出生成为Shape
要执行此向下转换功能,noShape
必须出生作为 Circle
对象。可以这样做:
Circle initialShape = new Circle();
现在您可以简单地将此 initialShape
对象向上转换为 Shape
对象。像这样
Shape upcastedObject = initialShape;
现在您可以将对象 upcastedObject
向下转换为其派生类,如
Circle derivedCircle = (Circle) upcastedObject;
现在 derivedCircle
对象的行为类似于 Circle
对象。因为它诞生于Circle
。我使用的是 BORN 这个词,所以请记住这一点。
这样做的原因或这样做的用例取决于您的要求。