public class Derived : BaseClass
{
public Derived(string name) : base(name) {}
public static implicit operator BaseClass(Derived derived)
{
return new BaseClass(derived.ColorHex);
}
public static implicit operator Derived(BaseClass baseclass)
{
return new Derived(baseclass.name);
}
}
这不起作用。为什么不允许?
我可以潜在地写出有必要的逻辑,特别是在从基础转换为派生的逻辑时。
编辑:更改了问题的标题
答案 0 :(得分:8)
因为已经存在从Derived
到BaseClass
的隐式转换,反之亦然。
关于后者:如果您的Base
对象可以隐式转换为Derived
- 为什么它们首先不是Derived
个对象?
6.1.6隐式参考转换
隐式参考转换是:
- [...]
- 从任何类型S到任何类型类型T,只要S是 源自T。
这表示存在隐式转化Derived
=> Base
,我们都知道。
6.2.4显式参考转换
显式引用转换为:
- [...]
- 从任何类型S到任何类型类型T,只要S是T的基类。
- [...]
这表示已经有明确的转化Base
=> Derived
(允许您在运行时尝试向下转换)。
6.4.1允许的用户定义转换
C#仅允许声明某些用户定义的转换。的在 特别是,不可能重新定义已经存在的 隐式或显式转换。
这说明由于两种兴趣转换已经由语言定义,因此您无法重新定义它们。
答案 1 :(得分:1)
因为它会扰乱多态性的结合。
答案 2 :(得分:1)
一般规则是将对象转换为自己的类型的结果是原始对象。如果类型BaseType
的存储位置包含DerivedType
的实例,则从原始类型转换为DerivedType
应该告诉编译器使用DerivedType
的成员,但是不应该实际上对对象“做”任何事情。如果允许自定义的从基础到派生的转换运算符,则有必要:(1)具有转换为实例的自有类型操作有时会产生新对象,有时不产生,或者(2)具有派生类型存储在基本类型存储位置中的对象与基本类型或不相关类型的对象的行为基本不同,没有明确可见的类型检查代码,这将使其这样做。虽然有时候人们可能想要一个方法,给定一个base-type参数,可能会返回一个新的派生类型对象,或者 - 如果给定一个派生类型的实例,只需返回它未经修改,通常更好的方法是有这样的东西“看起来”像一个方法而不是类型转换。
ValueType
,但每个值类型定义确实定义了两件事:一个派生自ValueType
的堆对象类型,以及一个不是对象的存储位置集合。不是来自任何东西。 C#定义了从后一种类型到前者的隐式转换运算符,以及从前者到后者的显式转换运算符。由于堆对象和存储位置集合之间的转换永远不会引用保留,因此允许在此类上下文中使用用户定义的转换运算符不会导致混乱的继承语义。这种转换的唯一困难是使用它们的值类型要么作为泛型类型不可用,要么如果作为泛型类型传递则会丢失它们的特殊行为。
答案 3 :(得分:0)
要合成,您可以将Derived对象转换为BaseClass对象,而无需编写任何代码:
BaseClass baseClass = new BaseClass("");
Derived derived = new Derived("");
baseClass = (BaseClass)derived;
但你无法将Derived中的强制转换重写为BaseClass。
对于其他演员,从BaseClass到Derived,它没那么有意义。
总之,只有在两个类之间没有继承关系时,才能重新定义强制转换。
答案 4 :(得分:0)
我需要能够从基础对象创建派生对象,以便捕获基类没有的其他信息。出于我的目的,构造一个派生对象,其中包含从基础对象复制的所有字段。我使用AutoMapper让我的生活更轻松:
String prefix = "ignore(FAILURE) { build(\"load\", ";
String ending = "}}";
for (String first: arr_1) {
for (String second: arr_2) {
System.out.println( prefix + first + second + ending);
}
for (String second: arr_3) {
System.out.println( prefix + first + second + ending);
}
for (String second: arr_4) {
System.out.println( prefix + first + second + ending);
}
}