在我的WPF程序中,我有一个C#代码区域非常重复,它看起来像这样:
protected void Page_Init(object sender, EventArgs e)
{
this.Page.LoadComplete += new EventHandler(this.Page_LoadComplete);
}
protected void Page_Load(object sender, EventArgs e)
{
this.DataBind();
}
protected void Page_LoadComplete(object sender, EventArgs e)
{
this.ddl.SelectedValue = "B";
}
protected void b_Click(object sender, EventArgs e)
{
Console.WriteLine("Updated");
}
所以我有一个想法,是否可以把它放在这样的for循环中:
labelFirst = EnglishPicker.SelectedColorText.Substring(0, 1);
labelLast = EnglishPicker.SelectedColorText.Substring(3, 6);
label = labelFirst + labelLast;
UpdateSetting("English", label);
labelFirst = PhotographyPicker.SelectedColorText.Substring(0, 1);
labelLast = PhotographyPicker.SelectedColorText.Substring(3, 6);
label = labelFirst + labelLast;
UpdateSetting("Photography", label);
寻求帮助的人的解决方案
使用SharedMethod,我能够缩短代码,因为EnglishPicker和PhotographyPicker是同一个类。代码:
string[] names = {"English","Photography"};
foreach (string name in names)
{
labelFirst = (name +"Picker").SelectedColorText.Substring(0, 1);
}
感谢那些帮助过我的人。 :)
答案 0 :(得分:3)
我认为你几乎已经在你的问题中找到了最简单的方法,但使用字符串来指代选择器可能会在运行时中断。
请改为尝试:
Picker[] pickers = { EnglishPicker, PhotographyPicker};
foreach (Picker picker in pickers)
{
labelFirst = picker.SelectedColorText.Substring(0, 1);
}
这里的优点是你有编译时的正确性,你可以明确地包含或排除你喜欢的任何选择器。
通过.Name
属性将控件重新转换为文本可以轻松更新设置。
答案 1 :(得分:2)
提供EnglishPicker
和PhotographyPicker
是属性:
您可以使用Reflection:
IEnumerable<string> names = new [] { "English", "Photography" };
foreach (string name in names)
{
// Build the property name
string propertyName = String.Concat(name, "Picker");
// Get Picker instance by locating the correct property
object picker = this.GetType().GetProperty(propertyName).GetValue(this);
// Get the SelectedColorText value from that instance
string colorText = (string) picker.GetType().GetProperty("SelectedColorText").GetValue(picker);
string first = colorText.Substring(0, 1);
string last = colorText.Substring(3, 6);
string label = String.Concat(first, last);
// Call UpdateSetting
UpdateSetting(name, label);
}
灵活性需要付出代价。
从属性查找到方法调用的所有内容都将在运行时完成,因此注意!它可以正常编译,但运行时可能会中断。
例如,如果您输错了"Enlgish"
而不是"English"
,则代码将完美编译。但是,在运行时,代码将尝试找到EnlgishPicker
属性并且它将失败。
此外,上述代码根本不具备防御性。
您应该更新它以包含空检查以避免潜在的异常。
答案 2 :(得分:1)
界面怎么样?根本不需要反思。这就是他们的目的。
public interface ISelectedColorContainer {
string SelectedColorText {get;}
}
实施
(我不知道你的课程是什么样的,但这就是我们使用界面的原因!)
public class EnglishPickerImplementation:ISelectedColorContainer {
public string SelectedColorText {get {return "sunflower";}}
}
public class PhotographyPickerImplementation:ISelectedColorContainer {
public string SelectedColorText {get {return "chartreuse";}}
}
所以你有一个看起来像这样的函数:
void SomeMethod(){
ISelectedColorContainer items = new ISelectedColorContainer[] {
new EnglishPickerImplementation(), new PhotographyPickerImplementation()};
foreach(var item in items){
var labelFirst = UpdateSetting(item);
var labelLast = item.SelectedColorText.Substring(3, 6);
var label = labelFirst + labelLast;
}
}
string UpdateSetting(ISelectedColorContainer input){
return input.SelectedColorText.Substring(0, 1);
}
很抱歉,如果有轻微的语法错误,我没有把它放在IDE中。
答案 3 :(得分:0)
我只是重构代码以在单独的方法中移动共享代码,而不是基于反射的解决方案。
示例:
i