查找对象的类型c#

时间:2014-07-28 14:15:33

标签: c# casting

我想编写一个方法,用于从另一个线程中使用,以更改多个button s textBox es等中的文本和颜色。

我希望它像

    public void ChangeUIPropertys(Object UIObject , Color color , string Text , ... )
    {
        switch (UIObject.GetType)
        {
            //switch cases 
            //...
            //...
            case Textbox :
             {
             //put here correct method with Invoke for correct cross Thread behavior 
             //DoSomething
             }
        }
    }

实现类似的东西的正确方法是什么?

8 个答案:

答案 0 :(得分:3)

很明显Object UIObject是Control,所以方法的定义可以改变,如

public void ChangeUIPropertys(Control UIObject , Color color , string Text)
{
    // to check control type
    if (control is TextBox)
    {
        var tb = (TextBox)control;
        // apply changes

    }
    else if (control is Label)
    {
         // do the same
    }
}

以线程安全的方式

public void ChangeUIPropertys(Control UIObject , Color color , string Text)
{
    // to make whole operation thread safe

    var action = delegate {
        // to check control type
        if (control is TextBox)
        {
            var tb = (TextBox)control;
            // apply changes

        }
        else if (control is Label)
        {
             // do the same
        }
    };

    if (control.InvokeRequired)
        control.Invoke(action);
    else
        action.Invoke();

}

答案 1 :(得分:2)

你不能使用switch。您应该使用if,可能:

if (UIObject is TextBox)
{
    // use UIObject
}

或者,如果您想将UIObject重新用作TextBox

TextBox tb = UIObject as TextBox;
if (tb != null)
{
    // use tb
}

如果从另一个线程调用,请确保在对象上使用Invoke以使用正确的线程。

答案 2 :(得分:2)

您可以将用作运算符:

  TextBox textBox = UIObject as TextBox;

  if (null != textBox) {
    // Do what you want with the textBox
  }

如果您想更改TextColor,只能使用抽象 控制 类:

  Control ctrl = UIObject as Control;

  // Both Button and TextBox
  if (null != ctrl) {
    ctrl.BackColor = Color.Red;
    ctrl.Text = "My Text";
  }

答案 3 :(得分:1)

由于Control基类实现了Text以及您提到的其他属性,您可以使用

foreach(var control in this.Controls.OfType<Control>())
    control.Text = "new text";

注意:这假设是Windows窗体,但此答案的其他版本可用

答案 4 :(得分:1)

虽然可以在这里处理case语句来处理调度(demo)但它不可靠。使用基于typeof的条件链也是如此。

更好的选择是使用内置的调度机制dynamic

public void ChangeUIPropertys(dynamic UIObject, Color color , string Text , ... ) {
    //                        ^^^^^^^
    ChangeUiPropertyImpl(UIObject, color, text);
}
private void ChangeUIPropertysImpl(Textbox tb, Color color , string Text , ...) {
    tb.SetColor(color);
}
private void ChangeUIPropertysImpl(Label lbl, Color color , string Text , ...) {
    lbl.SetColor(color);
}

一旦告诉C#UIObjectdynamic,它会在运行时找到ChangeUIPropertysImpl方法的最佳拟合覆盖。这为switch语句提供了一种非常快速的替代方法。

答案 5 :(得分:1)

这可能是replace the conditional with polymorphism的好机会。您可以定义一个抽象对象,例如:

abstract class UIObject
{
    abstract public void ChangeColor(Color color);
    // other operations
}

对于可以在其上执行此操作的每个UI元素,您可以定义具体实现:

class TextBoxObject : UIObject
{
    private TextBox uiElement;

    public TextBoxObject(TextBox textBox)
    {
        uiElement = textBox;
    }

    override public void ChangeColor(Color color)
    {
        // change the color of the text box
    }

    // other operations
}

然后消费代码将在抽象上运行,而不是(可能发生变化的)一组实现:

public void ChangeUIProperties(UIObject uiObject, Color color, string Text, ... )
{
    uiObject.ChangeColor(color);
    // other operations
}

这将是一种更加面向对象的方法,将特定于实现的功能封装到多态对象中,而不是长条件表达式。从消费代码的角度来看,类型本质上并不重要,实现细节被封装在抽象之后。

答案 6 :(得分:0)

获得对象的类型后,只需将其与typeof(Textbox)等进行比较。

答案 7 :(得分:0)

你可以这样做以避免2个cas(1个用于IS,1个用于使用控件):

var textbox = UIObject as Textbox;
if(textbox != null)
{
    // change color
}

var button = UIObject as Button;
if(button != null)
{
    // change color
}