【问题标题】:Casting System.Windows.Forms.Label to a custom type将 System.Windows.Forms.Label 转换为自定义类型
【发布时间】:2010-12-13 05:38:50
【问题描述】:

我有一个从 System.Windows.Forms.Control 派生的类

[Serializable]  
public class CommonControl : System.Windows.Forms.Control,IXmlSerializable 
{

基本上这个类为默认的 Controls 类增加了一些属性。 我的问题是我无法将 Control 对象转换为我的自定义控件对象。由于 customcontrol 类是从 Controls 派生的,我认为它可能会起作用。

我正在做这样的选角。

CommonControl ctrlTemp = new CommonControl();
ctrlTemp = (CommonControl)((Control)ctrl);

这里的 ctrl 是一个 Label 对象。当我调试第一次铸造工作正常。 (Control)ctrl 部分。但是当(CommonControl)((Control)ctrl) 被调试时,它会显示以下消息。

(CommonControl)(ctrl) 不能转换 'ctrl' (它的实际类型为 'System.Windows.Forms.Label') 到 'SharpFormEditorDemo.CommonControl' SharpFormEditorDemo.CommonControl

【问题讨论】:

    标签: c# winforms casting


    【解决方案1】:

    您不能跨类层次结构进行转换。 LabelCommonControl 都继承自 Control,但它们是不同的兄弟类,因此您不能将一个转换为另一个,甚至不能通过它们的父类进行转换。

    或者更简单地说:一旦创建了Label 对象,即使您将其转换为Control,它也始终是Label 对象。通过将其转换为 CommonControl,您将完全更改其类型,这在 C# 中是非法的。

    也没有多重继承。作为一种解决方法,您可以创建一个界面,然后创建您需要使用的控件的子类,这些子类都实现了您的自定义界面。一个快速而肮脏的例子:

    public interface ICommonControl : System.Xml.Serialization.IXmlSerializable {
        // ...
    }
    
    [Serializable]
    public class MyLabel : System.Windows.Forms.Label, ICommonControl {
        // Implement your common control interface and serializable methods here
    }
    

    然后创建ctrl 作为MyLabel 对象。它继承自Label,并采用您的类定义的所有接口方法。如果需要投射,请将其投射到 ICommonControl

    是的,您需要对每个控件类进行子类化,但这只是我能想到的一种解决方案。

    【讨论】:

    • 非常感谢。我应该考虑类层次结构。
    【解决方案2】:

    天哪,你知道你在做什么吗? ctrl 是标签,绝对不在 CommonControl 和 Control 之间的层次结构中。 您应该在 CommonControl 和 Control 层次结构之间将 ctrl 类型更改为您的用户定义类型,然后它将起作用。

    将 ctrl 转换为 Control 绝对没问题,因为 Label 是从 Control 派生的。但是将 ctrl 转换为 CommonControl 肯定是错误的,因为 ctrl 与 CommonControl 没有任何关系

    你可以做的是创建一个从 Label 派生的类,并使用 ctrl 来创建该类的对象。而那个类正在实现你想要的接口。

    【讨论】:

    • “天哪,你知道你在做什么吗?” - 没必要!
    • @geoff - 竖起大拇指 :) 即使我重视所有的答案.. 顺便说一句,我所做的有点愚蠢...... :D 谢谢大家。
    • sorry to be rude...我很抱歉...但实际上你可以拿起 1 或 2 本关于 C# 中的面向对象编程的书,希望它可以帮助你理解为什么 OO 并帮助你OO 设计您的程序。基本上,在您的情况下,您还可以创建一个接受任何 Control 对象的类,然后使用 is 运算符检查实际类型,并基于此进行序列化......再次抱歉......
    • 我对此表示赞同,尽管我在第一句话时有点畏缩。您走在正确的轨道上,其余的解释没有错。我什至有和你一样的最初反应,但我知道我们在这里回答问题时最好尽量控制我们的惊讶。 :-)
    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    相关资源
    最近更新 更多