对象类型的转换

时间:2011-01-28 09:47:55

标签: c# types casting

我有一堆像

这样的代码
if  control == typeof( GridCurrencyTextBox ))
{
    ((GridCurrencyTextBox)(_control)).Text = ....
}
if  control == typeof( TextBox ))
{
    ((TextBox )(_control)).Text = ....
}

等等。 我知道我可以通过control.GetType()估计类型,但.Text属性只能在知道编译时的类型时设置。

我想要像:

  Type t = _control.getType();
  (t(_control)).Text = .....

有什么建议吗?谢谢!

3 个答案:

答案 0 :(得分:3)

很难从你的问题中看出你实际问的是什么,但是你试过了吗?

ITextControl textControl = _control as ITextControl;
if(textControl != null)
{
    textControl.Text = //...
}

使用as进行投射将为您提供默认值(在这种情况下为null),如果您尝试投射的对象不是正确类型,并且据我所知.NET中的大多数(所有?)文本控件都派生自ITextControl(它只定义了Text属性)。

这假设您使用的是ASP.NET。正如其他人所提到的,在Windows窗体Control中有一个Text属性,因此您只需要确保已转换为Control,如果它已经是控件,则检查是不必要的(除了确保值不为空)。

如果您正在使用任何其他类型的Control并且它不是从提供Text属性的常见类型派生的,那么您可能不得不求助于使用反射,但这远非理想的它会很慢:

PropertyInfo text = _control.GetType().GetProperty("Text", BindingFlags.Public | BindingFlags.Instance, null, typeof(string), Type.EmptyTypes, null);
if(text != null)
{
    text.SetValue(obj, /* some value */, null);
}

答案 1 :(得分:0)

如果您使用的是.NET 3.0,则可以利用扩展方法重写代码,看起来更好一些。您的每个比较都包含几个小步骤:​​

  1. 检查特定类型
  2. 如果对象属于特定类型,则将其强制转换
  3. 对其执行某些操作
  4. 步骤1和2可以使用as - 运算符执行(您的目标必须是对象,因为as运算符只能转换引用类型)。第3步可以通过代表完成。因此,辅助函数可能如下所示:

    public static class Helper
    {
        public static void Do<T>(object obj, Action<T> action)
            where T : class
        {
            T castedObject = obj as T;
            if (castedObject != null && action != null)
                action(castedObject);
        }
    }
    

    然后你可以打电话:

    Helper.Do<TextBox>(control, delegate(TextBox obj) { obj.Text = "your text goes here"; });
    

    ...对于您必须处理的每种类型。此解决方案使用帮助程序类和匿名委托。

    这不是最好的解决方案。使用扩展方法和lambda表达式,您可以使用以下内容:

    public static class ObjectExtensions
    {
        public static void Do<T>(this T obj, Action<T> action)
        {
            if (obj != null && action != null)
                action(obj);
        }
    
        public static T Cast<T>(this object obj)
            where T : class
        {
            return obj as T;
        }
    }
    

    ...并使用:

    control.Cast<TextBox>().Do(t => t.Text = "your text goes here");
    

    您需要处理的每种类型。这条线比以前的解决方案更具可读性。但在这种情况下,你必须知道扩展方法和lambdas是如何工作的。

答案 2 :(得分:0)

如果你有财产并且你不知道类型,你可以随时这样做:

var type = _control.GetType();
var propertyInfo = type.GetProperty("Text");
if(propertyInfo!=null) propertyInfo.SetValue(_control,"Some Value");