C# 实例化对象时以编程方式使用字符串作为对象名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/314008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatically using a string as object name when instantiating an object
提问by emk
This is a contrived example, but lets say I have declared objects:
这是一个人为的例子,但可以说我已经声明了对象:
CustomObj fooObj;
CustomObj barObj;
CustomObj bazObj;
And I have an string array:
我有一个字符串数组:
string[] stringarray = new string[] {"foo","bar","baz"};
How can I programmatically access and instantiate those objects using the string array, iterating using something like a foreach:
如何使用字符串数组以编程方式访问和实例化这些对象,使用类似 foreach 的东西进行迭代:
foreach (string i in stringarray) {
`i`Obj = new CustomObj(i);
}
Hope the idea I'm trying to get across is clear. Is this possible in C#?
希望我试图表达的想法很清楚。这在 C# 中可能吗?
采纳答案by Jon Skeet
You need to be clear in your mind about the difference between an object and a variable. Objects themselves don't have names. Variable names are decided at compile-time. You can't access variables via an execution-time-determined name except via reflection.
您需要清楚地了解对象和变量之间的区别。对象本身没有名称。变量名是在编译时决定的。除了通过反射之外,您不能通过执行时间确定的名称访问变量。
It sounds like you reallyjust want a Dictionary<string, CustomObj>
:
听起来你真的只想要一个Dictionary<string, CustomObj>
:
Dictionary<string, CustomObj> map = new Dictionary<string, CustomObj>();
foreach (string name in stringArray)
{
map[name] = new CustomObj(name);
}
You can then access the objects using the indexer to the dictionary.
然后,您可以使用索引器访问字典的对象。
If you're really trying to set the values of variables based on their name at execution time, you'll have to use reflection (see Type.GetField). Note that this won't work for local variables.
如果您真的想在执行时根据变量的名称设置变量的值,则必须使用反射(请参阅Type.GetField)。请注意,这不适用于局部变量。
回答by Lasse V. Karlsen
You can't.
你不能。
You can place them into a dictionary:
您可以将它们放入字典中:
Dictionary<String, CustomObj> objs = new Dictionary<String, CustomObj>();
foreach (string i in stringarray)
{
objs[i] = new CustomObj(i);
}
But that's about as good as it gets.
但这也差不多了。
If you store the objects in fields in your class, like this:
如果将对象存储在类的字段中,如下所示:
public class SomeClass
{
private CustomObj fooObj;
private CustomObj barObj;
private CustomObj bazObj;
}
Then you can reach them through reflection. Let me know if that's the route you want to take.
然后你可以通过反思来接触他们。如果那是您要走的路线,请告诉我。
回答by Stefan Mai
This is possible using reflection if the variables are class member variables, but it's hideously slow for anything more than very specialized applications. I think if you detail what you're trying to do, we can better offer suggestions. There's very rarely a case where you should access a variable like you're doing.
如果变量是类成员变量,则可以使用反射来实现这一点,但是对于非常专业的应用程序以外的任何东西,它都非常慢。我想如果你详细说明你想要做什么,我们可以更好地提供建议。很少有您应该像正在做的那样访问变量的情况。
回答by Chris Kimpton
One option is the totally dynamic route, as per this article, where you specify a code block in a string and then compile/run it from within your program
一种选择是完全动态路由,根据本文,您可以在字符串中指定一个代码块,然后在程序中编译/运行它
回答by Chris Kimpton
Another option, less flexible, but simpler is via Activator.CreateInstance- where you ask for a new object to be created - it won't assign to dynamic variables, but is that needed?
另一种不太灵活但更简单的选择是通过Activator.CreateInstance- 您要求创建一个新对象 - 它不会分配给动态变量,但需要吗?
回答by Chris Kimpton
you can use a find function:
您可以使用查找功能:
public static Control FindControl(string controlId, Control container)
{
if (container.ID == controlId)
return container;
foreach (Control control in container.Controls)
{
Control c = FindControl(controlId, control);
if (c != null)
return c;
}
return null;
}
and then you will get your control, based on index like this: TextBox firstname = (TextBox) FindControl(string.Concat("TextBox", index.ToString()), this); I hope this helps.
然后你会得到你的控制,基于这样的索引: TextBox firstname = (TextBox) FindControl(string.Concat("TextBox", index.ToString()), this); 我希望这有帮助。
回答by Wildhorn
@jotte: Thanks alot for that function. I used it and it works! Except that you need to change container.ID by container.Name
@jotte:非常感谢这个功能。我用过它,它有效!除了您需要通过 container.Name 更改 container.ID
Then you just need to use something like (this example is for checkbox, but any type of variable could work):
然后你只需要使用类似的东西(这个例子是针对复选框的,但任何类型的变量都可以工作):
string Test = "cbACn" + i.ToString(); CheckBox cbTest = (CheckBox)FindControl(Test, gbACSCAT); if (cbTest != null) { cbTest.Checked = true; }
字符串测试 = "cbACn" + i.ToString(); CheckBox cbTest = (CheckBox)FindControl(Test, gbACSCAT); if (cbTest != null) { cbTest.Checked = true; }
回答by km1
use this.Controls.Find(control_name,true)[0]...just remember to cast it
使用 this.Controls.Find(control_name,true)[0]... 记得投它