Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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中的另一个派生类#_C#_Oop_Inheritance_Interface_Polymorphism - Fatal编程技术网

C# 将派生类强制转换为c中的另一个派生类#

C# 将派生类强制转换为c中的另一个派生类#,c#,oop,inheritance,interface,polymorphism,C#,Oop,Inheritance,Interface,Polymorphism,我有一个基本类: interface IBaseClass{ int x; int y; baseClass someMethod(); } 和一些派生类: class dClass1 : IBaseClass { int x; int y; baseClass someMethod(); } class dClass2 : IBaseClass { int x; int y; baseClass som

我有一个基本类:

interface IBaseClass{
     int x;
     int y;
     baseClass someMethod();
}
和一些派生类:

class dClass1 : IBaseClass {
     int x;
     int y;
     baseClass someMethod();
}
class dClass2 : IBaseClass {
     int x;
     int y;
     baseClass someMethod();
}
根据子类算法的属性值不同于其他子类 现在我想将这些子类转换为它们:

dClass1 c1=new dClass1 ();
c1.x=4;
c1.y=5;
dClass2 c2=c1;//cast to dClass2 , but value of property set by  according to the own algorithm  
Console.WriteLine("{0}, {1}", c1.x, c1.y);//4,5
Console.WriteLine("{0}, {1}", c2.x, c2.y);//7,1

dClass1
dClass2
是两种不同的类型。你不能直接把一个扔给另一个。你必须把一个换成另一个。例如:

dClass1 c1 = new dClass1
{
    x=4,
    y=5
};
dClass2 c2 = new dClass2
{
    x = c1.x,
    y = c1.y
};
或者,像原始代码一样使用多行:

dClass1 c1 = new dClass1();
c1.x=4;
c1.y=5;
dClass2 c2 = new dClass2();
c2.x = c1.x;
c2.y = c1.y;

关键是,系统无法直接将一种类型转换为另一种类型。您可以将此转换封装到任何类型或单独类上的工厂方法中。但选角不是一个选择。仅仅因为这两种类型的成员具有相同的类型/名称/等等,并不意味着它们具有相同的类型。

您尝试执行的操作是不可能的。可以将对象强制转换为较少(在某些情况下为更多)的派生类型,但不能将对象强制转换为其他类型,除非对该类型定义自定义强制转换


您可以在此处阅读有关定义自定义强制转换的内容:

首先,让我们明确指出,
IBaseClass
不是一个基类,它是一个
接口
,这是完全不同的。指出差异不在本答案的范围内,但您可以从一开始就轻松阅读

也就是说,正如其他人所说,你不能直接做你想做的事。考虑典型的例子:代码> iStabor <代码>,<代码>狗< /代码>,代码>猫>代码>等。Eviy狗和每只猫都是动物,但猫不是狗,狗不是猫,你基本上是要求猫是狗;你首先需要教猫如何狗化(它们不会为你做现成的事情)

为了实现这种行为,有很多方法可以做到:

  • 用户定义的强制转换:您可以定义从一个类转换为另一个类的运算符。如果您使它们
    隐式
    ,您甚至可以按现在的方式编译代码:

    public static implicit operator dClass2(dClass1 obj)
    { //logic to convert obj to corresponding new dClass2 instance }
    
    现在这将是合法的:

    var c1 = new dClass1();
    dClass2 c2 = c1; // implicit cast operator is called.
    
    请注意,如果要将cast操作符实现为显式的,那么前面的代码将不会编译。您需要显式强制转换
    c1

    var c2 = (dClass2)c1;
    
  • 定义接受
    dClass1
    参数的
    dClass2
    构造函数:

    public dClass2(dClass1 obj) { ... }
    
    您将编写以下代码:

    var c1 = new dClass1();
    var c2 = new dClass2(c1);
    
  • dClass2
    中定义一个静态工厂方法,该方法接受
    dClass1
    参数并生成一个新的
    dClass2
    实例:

    public static dClass2 CreateFrom(dClass1 obj) { ... }
    
    以及相应的代码:

    var c1 = new dClass1();
    var c2 = dClass2.CreateFrom(c1);
    
  • 还有很多我都懒得去想

  • 你选择哪一个取决于个人品味。我可能会使用显式强制转换,但任何可用的选项都没有本质上的错误。

    您不能这样做。您可以将dClass1和dClass2都强制转换为IBaseClass,因为它们都是IBaseClass。无法将dClass1强制转换为dClass2,因为dClass1不是dClass2。我认为你对C#类的本质理解有误。@EdPlunkett——它比“C#类的本质”更广泛。它是面向对象编程的基本原则之一:多态性。@roryap好吧,我想尝试一下C++98(
    ((dClass2*)&c1)
    ,而不是
    dynamic\u cast
    )(这并不是一个好主意,只是你可能会幸运地得到两者相同的布局),而在JavaScript中,它会非常有意义。我不是计算机科学家,我是个笨手笨脚的人。