我想要一个c#应用程序,我可以在其中使用int变量或保存在数组中的名称来修改指定的对象(但我更喜欢使用int)。
这样的事情:
如果我有3个名为bt1
,bt2
和bt3
的按钮,则图片路径是我的图片=“\”的路径。
int btnum = 1;
bt + num .backgroundpicture=picturepath+num+".png";
btnum +=1;
bt + num .backgroundpicture=picturepath+num+".png";
btnum +=1;
bt + num .backgroundpicture=picturepath+num+".png";
因此,应将backgroundpicture
的{{1}}设置为bt1
,picturepath1.png
设置为backgroundpicture
至bt2
和{{1} bt3到picturepath2.png
。
(在实际场景中,我会使用或使用许多对象,或者在运行代码时创建未指定数量的对象。)
答案 0 :(得分:2)
您不应该依赖变量的名称,因为那些可能会发生变化的实现细节。
不是让三个变量引用一个按钮,而是使用包含所有按钮的列表并引用由索引指定一个:
var buttons = new List<Button> { btn1, btn2, btn3 };
buttons[btnNumber - 1].BackGroundImage = ...
请注意,数组和列表是从零开始的,因此您必须减去一个。例如。获得btn1
你需要buttons[0]
。
答案 1 :(得分:0)
把它做成循环,就像这样:
int BtnNum = 1;
int BtnNumUWant = 3;
int X = 10;
int Y = 10;
string pictureName = "picturepath";
while (BtnNum < BtnNumUWant + 1)
{
Button Btn = new Button();
Btn.Name = "Btn" + BtnNum.ToString();
Btn.BackgroundImage = Image.FromFile(Path.Combine(path, pictureName + BtnNum.ToString() + ".png"));
Btn.Location = new Point(X, Y);
Btn.Text = Btn.Name;
Btn.Parent = this;
BtnNum++;
Y += 100;
}
那应该做你想要的。
由于您希望在运行代码时创建一个未指定数量的对象,因此最好动态创建按钮并在窗体(或文本或其他)上设置位置。那个循环。
答案 2 :(得分:0)
另一种方法是,如果你想真正访问和影响某些对象,基于它具有的属性(动态),并且仍然没有完全DLR的网格,请使用Linq表达式:
所以对某些对象(例子)
public class ExampleClass {
public Button bt1 { get; set; }
public Button bt2 { get; set; }
.....
}
您可以从属性中构建一个mutator工厂并动态制作分配,如下所示:
var instance = Expression.Parameter(typeof(ExampleClass));
Where 子句是可选的 - 只是根据您的情况调整
var propertiesAffected = instance.Type.GetProperties().Where(x => RegEx.IsMatch(x.Name, "[A-Za-z]+\d+")).Select(p => Expression.MakeMemberAccess(instance, p)).ToList();
现在,此示例方法是工厂方法构建器,将分配逻辑定义为二进制表达式,收集这些并构建一个Action - 然后根据您的要求,它可以按类型重用。您也可能会注意到,将ExampleClass与Generic Argument交换并将约束类型转换为类是非常简单的:
public Action<T> BuildAssignments<T>(Expression instance, IEnumerable<MemberExpression> propertiesAffected) where T : class {
List<Expression> operations = new List<Expression>();
foreach (var pr in propertiesAffected) {
int num;
string extract = RegEx.Match(pr.Name, "(\d+)$").Value;
if (!string.IsNullOrWhitespace(extract)) {
num = Int.Parse(extract);
// This is to wrap the calculated value as a constant value
var target = Expression.Constant($"{picturepath}{num}.png");
// Assign the property access of BackgroundPicture from pr (so the idea of instance.bt1.BackgroundPicture) to the templated value constructed
operations.Add(Expression.Assign(Expression.PropertyOrField(pr, "BackgroundPicture"), target));
}
}
return Expression.Lambda<Action<ExampleClass>>(operations, instance).Compile();
}
如果由于某种原因您只想限制为Button类型,则MemberExpressions是优秀的元数据处理程序,比使用直接反射/ Activator代码更有效。这允许您动态收集所有看起来像bt1,bt2或img1,img35 ...的属性,并根据您的请求将它们分配给模板化输出名称,如果正确构建一次,则输入安全且极其高效,并重用于生命周期型
最终这次通话的结果将是
var mutator = BuildAssignments<ExampleClass>(instance, propertiesAffected);
var model = new ExampleClass();
mutator(model);
// model will have properties assigned! This access is the reused item -- cache it early and save on processing