我有一个从各种Windows控件返回相关文本的功能。
我希望能够创造出一些更优雅,更不静态的东西。
这是我想要的功能代码:
public string returnText(Control controller)
{
string bob = controller.GetType().Name.ToString();
if (bob == "TextBox")
return ((TextBox)controller).Text;
else if (bob == "ComboBox")
return ((ComboBox)controller).SelectedValue.ToString();
else
return "Invalid Object";
}
我想做的是这样的:
呼叫代码:
TextBoxValue del = x => x.Text;
ComboBoxValue com = x => x.SelectedValue.ToString();
bob.returnText2(this.cboUnitType, com);
bob.returnText2(this.txtCurbAdj, del);
功能:
public string returnText2<T>(T controller, Func<T, string> lambda )
{
return lambda(controller);
}
我猜我在做错误的一般性方面,但是我还没有找出正确的方法来做。 或者也许我完全在这里吃午饭。
答案 0 :(得分:2)
这是原始代码的更清晰版本。它不使用任何反射,泛型或ToString调用。相反,它使用 pattern matching 开关语句:
public static string ReturnText(Control control)
{
switch (control)
{
case TextBox tb:
return tb.Text;
case ComboBox cb:
return cb.SelectedText;
//etc.
default: return string.Empty;
}
}
顺便说一句,您将名称 controller
用于类型Control
的变量会产生误导;控制器在其他情况下具有实际意义。
一种替代方法是创建一个Dictionary<Type, Func<Control, string>>
,其中的条目看起来像{typeof(Textbox), c=>((TextBox)c).Text}
,但是我认为这比仅使用如上所示的开关要清楚得多。
另一件事:您可以将此功能设为Control
类型的扩展方法(通过将其放在静态类中,然后将关键字{参数列表中this
之前的{1}}。我可能会将其重命名为Control
。那时,您只需为页面上的任何控件说GetTextValue
。不幸的是,C#中还没有var textValue = anyControl.GetTextValue();
答案 1 :(得分:0)
使用反射非常容易。您要做的是使用类的类型来检索其属性。然后,您在对象上请求该属性的值,就得到了该值。
这里是一个简单的快速反思。其作用是获取对象的类型,请求名为SelectedValue
的属性,然后查询combobox
对象以获取值,最后将其转换为字符串。
var combobox = this.cboUnitType;
var value = combobox.GetType().GetProperty("SelectedValue").GetValue(combobox ).ToString();
在同一函数中添加了同样的内容,并且很通用,而且可能会发生错误处理
private string GetValue(object obj, string property)
{
var value = "";
try
{
value = obj.GetType().GetProperty(property).GetValue(obj).ToString();
}
catch { }
return value;
}