得到&可以使用Object.GetType()设置实际对象类型吗?

时间:2014-05-20 01:33:26

标签: c# winforms

我正在尝试创建一个返回实际控件的函数。我知道当你知道对象的类型时你可以这样做:

public static Control GetCtl(this object obj)
{
    //(obj as obj.GetType()) ?
    return (TextBox)obj;
}

但是,如果我需要从其他(未知)对象类型中获取一个,例如TextBox或RichTextBox,该怎么办?然后我将使用它:

private void TextBox1_Click(object sender, EventArgs e)
{
    sender.GetCtl().Select(0, 0);
}

虽然TextBoxRichTextBox似乎有相同的Select方法,但当我尝试使用上述GetCtl()函数时,它总是会出错。我该怎么做呢?

修改: 由于您无法在所有本机过程/方法(即sender_Click())中以_MouseMove()访问“完整”控件属性,因此我想创建一个可以返回实际控件的函数,而不是确定如何更好地解释这一点,但这是我将如何使用它:

Private void SomeControl_KeyDown(object sender, KeyEventArgs e){
    sender.getCtl().   //<-- so I can access anything here

    (sender as Button).Text = "sometext"  // <-- so I won't have to do this

    //I wish the following would work. But you get the idea
    (sender.GetType())sender.Text = "";
    //or...
    (sender as sender.GetType()).Text = "";
}

1 个答案:

答案 0 :(得分:2)

RichTextBoxTextBox均来自TextBoxBase

要告诉编译器您要将对象视为特定类型,可以执行强制转换操作。在这种情况下,您需要将sender投射到TextBoxBase,然后才能访问Select()方法:

private void TextBox1_Click(object sender, EventArgs e)
{
    var textbox = sender as TextBoxBase;
    if (textbox != null)
        textbox.Select(0, 0);
}

这使用as keywordsender对象转换为TextBoxBase。请注意,您不能简单地将任何内容转换为其他内容。被强制转换的对象实际上必须是您要转换为的类型的实例。如果sender不是从TextBoxBase派生的事物的实例,则强制转换操作将返回null。

通常,winforms事件处理程序只应在非常受控和已知的情况下引发 - 您应该非常确信此事件是由从TextBoxBase派生的控件引发的。从其他任何事情中提出它都没什么意义。

如果你真的想要一个方法将发送者转换为TextBoxBase,你可以把它写成:

private TextBoxBase ToTextBoxBase(object sender)
{
    var textbox = sender as TextBoxBase;
    if (textbox == null)
        throw new Exception("The given object is not derived from TextBoxBase");

    return textbox;
}

您可以使用它:

ToTextBoxBase(sender).Select(0, 0);

如果发件人不是TextBoxBase,则此调用将抛出“给定对象不是从TextBoxBase派生”异常。

要理解的重点是您正在使用强类型语言。如果你试图调用一个不是包含该方法的类型的对象的方法,程序甚至不会编译(除非类型是dynamic,但这是另一个讨论)。

可以创建一个可以使用以下语法调用的方法:

sender.ToTextBoxBase()

这称为extension method。但是,您将扩展System.Object类用于非常特定的目的,这是不推荐的。