【问题标题】:Up casting - c#向上铸造 - c#
【发布时间】:2025-12-08 22:25:01
【问题描述】:
public class a{
  public string x1 {get;set;}
  public string x2 {get;set;}
  public string x3 {get;set;}
}

public class b:a{
}

显然var foo = (b)new a(); 会在运行时抛出一个转换错误。

我认为分配已实例化和填充的a 的所有属性的唯一另一种方法是将每个属性手动复制到b 的新实例中。

这是正确的吗?

【问题讨论】:

  • 你的问题是关于downcasting,你的问题标题是关于upcasting。 – 哪个是正确的?
  • @Konrad Rudolph:将a 转换为b 是一种“向上转换”
  • @Konrad 啊,我认为这是“向上转换”,因为我正在将“a”转换为“更高”类。
  • @leppie 不。至少不是按照通用术语。见Wikipedia: DowncastingJava glossary: upcasting
  • @Konrad Rudolph:好的。对我来说,向下转换意味着转换为限制较少的类型。

标签: c# .net casting


【解决方案1】:

这种类型的转换是错误的,因为您不能将父母转换为他们的孩子。
a 类型不知道 b 类型的元信息。因此,您需要提供显式转换运算符来执行此类操作,但在这种情况下,您必须移除继承
其他选项是定义一些接口,例如在其他问题中。

更多信息:
http://msdn.microsoft.com/en-us/library/ms173105.aspx
http://msdn.microsoft.com/en-us/library/85w54y0a.aspx

【讨论】:

  • 不允许通过显式运算符向上转换。编译器会抱怨。
  • @VMAtm:2 种不相关的类型都可以。但是尝试使用父子类型。卡布姆!
  • 哎呀。不知道。谢谢。
  • 向上转换和向下转换都不使用用户定义的转换。
【解决方案2】:

不可能。即使你认为你拥有它,编译器也会抱怨。

这通常表示设计或逻辑错误。

【讨论】:

  • @maxp:当“你有它”时,意味着创建一个显式转换运算符,这将无法编译。
【解决方案3】:

这也是一直困扰我的事情。 我通过创建自己的 Up-Casting 实用程序找到了解决方案。

您可以在此处阅读我的文章,了解如何操作 - 实际上非常简单。

http://sympletech.com/c-up-casting-utility/

【讨论】:

    【解决方案4】:

    你不能做那个演员。

    你可以,而且我猜你应该使用接口。

    public interface ia
    {
        string x1 { get; set; }
        string x2 { get; set; }
        string x3 { get; set; }
    }
    public class a : ia
    {
        public string x1 { get; set; }
        public string x2 { get; set; }
        public string x3 { get; set; }
    }
    
    public class b : a, ia
    {
    }
    

    那你就可以了

    ia foo = new a();
    

    【讨论】:

      【解决方案5】:

      实际上,您创建 b 的新实例并将 a 的字段值复制到其中的想法似乎是一种有趣的方法。使用反射来实现这一点应该很适合。

      类似于:遍历 a 的所有字段,获取它们存储在 a 中的值并将它们存储在 b 中的同一字段中。

      不过,这不是“向下转换”——因为这意味着创建了一个完全不同的对象——而不是重新解释现有对象的含义。

      【讨论】:

        【解决方案6】:

        正如大家所说,这是不可能的。隐式转换是一种解决方案,但我更喜欢在 b 上创建一个构造函数,它采用 a 类型的实例...

        这样你可以:在内部持有对 a 的引用并委托给它调用从 a 继承的 b,或者只是简单地从类型 a 中复制值。

        【讨论】: