Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将基类型转换/强制转换为派生类型_C#_.net - Fatal编程技术网

C# 将基类型转换/强制转换为派生类型

C# 将基类型转换/强制转换为派生类型,c#,.net,C#,.net,我通过派生现有的.NET framework类来扩展它。如何将基类型的对象转换为派生类型 public class Results { //Framework methods } public class MyResults : Results { //Nothing here } //I call the framework method public static MyResults GetResults() { Results results = new Results();

我通过派生现有的.NET framework类来扩展它。如何将基类型的对象转换为派生类型

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

如何在不进行手动复制的情况下执行此操作?

如何:

...
MyResults results  = new MyResults();
...
您可能还需要在
MyResults
类中创建构造函数:

public class MyResults : Results
{
    public MyResults() : base() {}
}
“这里什么都没有”到底是什么意思

编辑

 results = (CallFrameworkMethod() as MyResults);

它不会抛出异常,但是如果它对您有用的话-这取决于您想进一步做什么…

您不能。如果
results
没有引用
MyResults
(例如,如果
CallFrameworkMethod
返回一个基本
results
实例),那么casting将不会这样做:您需要基于现有的非
MyResults
创建一个新的
MyResults
。强制转换是关于更改引用的编译时类型,而不是更改引用对象的具体类型

您可以使用反射或自动映射等工具帮助初始化新的
MyResults
对象,但必须有一个新的
MyResults
对象,因为您无法告诉基本
Results
对象成为
MyResults
对象

Results results = new MyResults();
   ...

return (MyResults)results;

应该有用。如果不是,那么问题也在某个地方。

否,您无法避免将内容复制到派生类型的实例中。如果您可以将CallFrameworkMethod更改为泛型方法,并且MyResults具有零参数构造函数,那么CallFrameworkMethod可以直接创建派生类型的新实例,然后仅使用父类型的成员


但你可能不得不复制到一个新的对象上。请记住,此复制代码当然可以在另一个方法中重用,您不必在任何需要的地方重写它。

正如前面的答案所述,您需要实例化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
};

如果有很多属性和/或您正在对类进行大量更改,您可以使用反射(例如)或AutoMapper()等工具来复制这些属性。但这通常是过分的。

要将对象向下转换到其派生类中,对象必须出生在其派生类中。 例如: 我有一个简单的类叫做Shape 下面是Shape类的代码

public class Shape{
     public void draw(){}
}
然后我还有一个名为Circle的类,如下所示:

public class Circle:Shape{
      public void drawCircle(){}
}
现在如果我创建一个超类的对象,比如

Shape noShape = new Shape();
Circle derivedCircle = (Circle) upcastedObject;
如果试着把这个
noShape
对象向下投影到
Circle
像这样的对象上

Circle circle = (Circle) noShape; 
Shape upcastedObject = initialShape;
它将生成一个异常。这是因为
circle
从来就不是作为
Shape
要执行此向下投射功能,
noShape
必须作为
Circle
对象生成。可以这样做:

Circle initialShape = new Circle();
现在您可以简单地将这个
initialShape
对象向上转换为
Shape
对象。像这样

Circle circle = (Circle) noShape; 
Shape upcastedObject = initialShape;
现在可以将对象
upcastedObject
向下转换为其派生类,如

Shape noShape = new Shape();
Circle derivedCircle = (Circle) upcastedObject;
现在,
derivedCircle
对象的行为将类似于
Circle
对象。因为它是以圆圈的形式诞生的。我用的是出生这个词,所以请记住这一点。
这样做的原因或这样做的用例取决于您的要求。

否,因为他随后会用CallFrameworkMethod的返回值覆盖它——这可能会返回MyResults以外的内容,他创建了MyResult类的一个实例,然后调用CallFrameworkMethod方法,该方法为results对象分配了另一个无法强制转换的实例。“此处为nothing”,就像字面上的nothing一样。现在,我继承了基类型,目的是在将来添加新属性。我编辑了我的答案-请检查新的解决方案。@Gacek-使用as关键字不会引发异常,但MyResult对象为null,尽管CallFrameworkMethod返回的是非null对象。关于编辑:如果CallFrameworkMethod返回的是
结果
而不是
MyResults
,则只需设置编辑
结果
为空。强制转换仍然失败,但是
as
操作符通过返回null而不是抛出异常来指示这一点。结果类中是否存在允许基于其他对象创建一个对象的构造函数?类似于
结果(结果引用对象)
?如果是这样,您可以在类中实现类似的构造函数(通过派生原始构造函数),然后像这样调用它:
var results=new MyResults(CallFrameworkMethod())这与方差/协方差有关吗?我在.NET4.0上,我知道他们为方差/协方差做了一些事情。有什么想法吗?没有,C#4.0的差异与使用基/派生类型作为泛型接口或委托的类型参数有关;这里没有任何通用接口或委托。您的问题更为根本:它与对象的具体类型有关。结果对象不是MyResults类型的实例。如果CallFrameworkMethod返回(实际)结果,则对该对象的引用不能强制转换为MyResults,因为该对象不是MyResults。解决此问题的唯一方法是更改CallFrameworkMethod以返回MyResults,或创建新的MyResults。您可以只创建扩展方法而不是扩展类型吗?这是一个好主意。具有