Я хочу выполнить оператор C#, который хранится в строковой переменной. Например:Выполнение оператора C#, хранящегося в строковой переменной
string statement1 = "button1.Visible = true";
string statement2 = "button1.Text = \"Number\"";
Я хочу выполнить оператор C#, который хранится в строковой переменной. Например:Выполнение оператора C#, хранящегося в строковой переменной
string statement1 = "button1.Visible = true";
string statement2 = "button1.Text = \"Number\"";
Глядя на ваши комментарии, и что у вас есть 80 элементов управления, требующих очень аналогичные действия, динамическая компиляция может быть избыточна для этой цели. Вы можете использовать коллекцию родительского контейнера Controls
вместе с свойством Tag
ваших кнопок для его достижения. Достаточно одного обработчика событий.
Вы можете использовать элементы LINQ, такие как OfType
и Cast
, чтобы сделать ваш код еще меньше.
Редактировать
После просмотра ваших последних комментариев, что вы должны сделать, это программно создавать свои кнопки и добавить их в свой Form
или любой контейнер у вас есть. Затем вы можете сохранить Dictionary<string, Button>
, который позволит вам либо перебирать коллекцию, либо получить доступ к отдельной кнопке через свое имя. Что-то вроде:
//Declare this globally
Dictionary<string, Button> Dic = new Dictionary<string, Button>(81);
//put this in the constructor
for(int i=0; i<81; i++)
{
Button b = new Button();
b.Text = i; //or Random or whatever
b.Name = "btn" + i.ToString();
this.Controls.Add(b);
Dic.Add(b.Name, b);
}
Позже вы можете сделать как итерации так:
foreach(var item in Dic)
{
item.Value.Visible = true; //or false
}
и ключ доступа на основе, как это:
Dic["btn45"].Visible = true; //or false
Поскольку вы создаете судоку, я, вероятно, подумайте, что вы должны использовать TableLayoutPanel
с соответствующим количеством строк и столбцов во время разработки, а затем добавить свои кнопки в панель и установить их свойство Row/Column в цикле. Это поможет лучше реагировать на события изменения размера и т. Д.
объясните, пожалуйста, кратким примером, пожалуйста, –
Plz предоставляет некоторые детали фактическая задача, и я могу написать код для примера. – dotNET
Я думаю, что @Lasse V. Karlsen сделал что-то, что я хочу сделать –
Из ваших комментариев кажется, что вы просто хотите перебрать более 80 похожих кнопок и настроить их одинаково. Это может быть выполнено гораздо проще, чем выполнение динамического кода.
Вот несколько способов.
установить свойство Tag для определенного числа в конструкторе для каждой из кнопок 80.
Затем выполнить этот код:
foreach (var button in Controls.OfType<Button>().Where(button => button.Tag == "TAG"))
{
button.Visible = true;
button.Text = "Number";
}
Убедитесь, что все кнопки 80 имеет название «buttonX», где X представляет собой число.
Затем выполнить этот код:
foreach (var button in Controls.OfType<Button>().Where(button => button.Name.StartsWith("button"))
{
button.Visible = true;
button.Text = "Number";
}
Если, как вы говорите, в комментариях, вам нужно только решить эту проблему: «Выполнить» этот тип кода:
object.member=value
Где object
относится к чему-то хранится в поле или свойство.member
относится к публичному члену (поле или свойство) этого объекта, а value
- это то, что всегда будет легко конвертироваться в тип члена, тогда будет работать следующий код.
Обратите внимание, что проверка ошибок невелика, поэтому убедитесь, что вы проверили код перед его использованием.
ТАКЖЕ Я не убежден в том, что это подходящее решение, но поскольку вы решили спросить о решении, которое вы имели в виду, а не о реальной проблеме, трудно найти лучшее решение.
Вы можете запустить этот код в LINQPad:
void Main()
{
button1.Dump();
SetProperties(this,
"button1.Visible=true",
"button1.Text=\"Number\""
);
button1.Dump();
}
public static void SetProperties(object instance, params string[] propertySpecifications)
{
SetProperties(instance, (IEnumerable<string>)propertySpecifications);
}
public static void SetProperties(object instance, IEnumerable<string> propertySpecifications)
{
var re = new Regex(@"^(?<object>[a-z_][a-z0-9_]*)\.(?<member>[a-z_][a-z0-9_]*)=(?<value>.*)$", RegexOptions.IgnoreCase);
foreach (var propertySpecification in propertySpecifications)
{
var ma = re.Match(propertySpecification);
if (!ma.Success)
throw new InvalidOperationException("Invalid property specification: " + propertySpecification);
string objectName = ma.Groups["object"].Value;
string memberName = ma.Groups["member"].Value;
string valueString = ma.Groups["value"].Value;
object value;
if (valueString.StartsWith("\"") && valueString.EndsWith("\""))
value = valueString.Substring(1, valueString.Length - 2);
else
value = valueString;
var obj = GetObject(instance, objectName);
if (obj == null)
throw new InvalidOperationException("No object with the name " + objectName);
var fi = obj.GetType().GetField(memberName);
if (fi != null)
fi.SetValue(obj, Convert.ChangeType(value, fi.FieldType));
else
{
var pi = obj.GetType().GetProperty(memberName);
if (pi != null && pi.GetIndexParameters().Length == 0)
pi.SetValue(obj, Convert.ChangeType(value, pi.PropertyType));
else
throw new InvalidOperationException("No member with the name " + memberName + " on the " + objectName + " object");
}
}
}
private static object GetObject(object instance, string memberName)
{
var type = instance.GetType();
var fi = type.GetField(memberName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default);
if (fi != null)
return fi.GetValue(instance);
var pi = type.GetProperty(memberName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default);
if (pi != null && pi.GetIndexParameters().Length == 0)
return pi.GetValue(instance, null);
return null;
}
private Button button1 = new Button();
public class Button
{
public bool Visible;
public string Text { get; set; }
}
Этот выход (два button1.Dump();
операторов) настройки кнопки до и после, и вы заметите, что свойство и поле было установлено.
Вы можете выполнить это следующим образом:
`SetProperties(this, "...", "...");
где this
должны относиться к вашей форме объекта (тот, который владеет кнопки).
Мне сложно представить игровой экран с 80 (ВОСЕМЬ), каждый из которых говорит «Число», и те, которые тоже появляются сразу ... :) – dotNET
Да, мне тоже, но мне трудно понять, что еще это может означать. –
«Номер» был всего лишь примером, на самом деле его игра в судоку, содержащая 81 пуговицу, спасибо за помощь @dotNET и @ Lasse :) –
Как насчет использования делегатов?
Action statement1 =() => button1.Visible = true;
Action statement2 =() => button1.Text = "Number";
Вы говорите, что строка содержит опубликованный код? –
Что ты говоришь? – dotNET
yes @ LasseV.Karlsen –