将控件视为ComboBox或TextBox

The*_*gth 10 .net c# generics

解决以下问题的最佳方法是什么?

foreach (Control control in this.Controls)
{
    if (control is ComboBox || control is TextBox)
    {
        ComboBox controlCombobox = control as ComboBox;
        TextBox controlTextbox = control as TextBox;

        AutoCompleteMode value = AutoCompleteMode.None;

        if (controlCombobox != null)
        {
            value = controlCombobox.AutoCompleteMode;
        }
        else if (controlTextbox != null)
        {
            value = controlTextbox.AutoCompleteMode;
        }

        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

您会发现它足够复杂以获取AutoCompleteMode属性.您可以假设我保证我有一个ComboBox或一个TextBox.

我的第一个想法是为T使用多种类型的泛型,但似乎这在.NET中是不可能的:

public string GetAutoCompleteModeProperty<T>(T control) where T: ComboBox, TextBox // this does not work, of course
Run Code Online (Sandbox Code Playgroud)

可悲的是,两个控件都没有共同的基类.

注意:这是一个与最小化示例一起使用的更一般的问题.在我的例子中,我还想访问/操纵其他AutoComplete*-proprties(两个控件都有共同点).

谢谢你的想法!

Bog*_* M. 6

dynamic currentControl =  control;
string text = currentControl.WhatEver;
Run Code Online (Sandbox Code Playgroud)

但是,如果currentControl没有Wha​​tEver属性,它会抛出异常(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)

  • 在这种情况下我不认为你应该使用`dynamic`关键字 - [见这个问题](http://stackoverflow.com/q/2674906/463828) (5认同)

Luk*_*ley 1

使用Type.GetType()。您只需输入string您的财产的表示形式即可。

if (sender is ComboBox || sender is TextBox)
{
  var type = Type.GetType(sender.GetType().AssemblyQualifiedName, false, true);
  var textValue = type.GetProperty("Text").GetValue(sender, null);
}
Run Code Online (Sandbox Code Playgroud)

这也允许您设置属性的值。

type.GetProperty("Text").SetValue(sender, "This is a test", null);
Run Code Online (Sandbox Code Playgroud)

您可以将其移至辅助方法以节省重写代码。

public void SetProperty(Type t, object sender, string property, object value)
{
  t.GetProperty(property).SetValue(sender, value, null);
}
public object GetPropertyValue(Type t, object sender, string property)
{
  t.GetProperty(property).GetValue(sender, null);
}
Run Code Online (Sandbox Code Playgroud)

使用此方法还可以进行异常处理。

var property = t.GetProperty("AutoCompleteMode");
if (property == null)
{
  //Do whatever you need to do
}
Run Code Online (Sandbox Code Playgroud)