2013-09-30 3 views
-4

Я хочу выполнить оператор C#, который хранится в строковой переменной. Например:Выполнение оператора C#, хранящегося в строковой переменной

string statement1 = "button1.Visible = true"; 
string statement2 = "button1.Text = \"Number\""; 
+0

Вы говорите, что строка содержит опубликованный код? –

+0

Что ты говоришь? – dotNET

+0

yes @ LasseV.Karlsen –

ответ

2

Глядя на ваши комментарии, и что у вас есть 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 в цикле. Это поможет лучше реагировать на события изменения размера и т. Д.

+0

объясните, пожалуйста, кратким примером, пожалуйста, –

+0

Plz предоставляет некоторые детали фактическая задача, и я могу написать код для примера. – dotNET

+0

Я думаю, что @Lasse V. Karlsen сделал что-то, что я хочу сделать –

1

Из ваших комментариев кажется, что вы просто хотите перебрать более 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 должны относиться к вашей форме объекта (тот, который владеет кнопки).

+0

Мне сложно представить игровой экран с 80 (ВОСЕМЬ), каждый из которых говорит «Число», и те, которые тоже появляются сразу ... :) – dotNET

+0

Да, мне тоже, но мне трудно понять, что еще это может означать. –

+0

«Номер» был всего лишь примером, на самом деле его игра в судоку, содержащая 81 пуговицу, спасибо за помощь @dotNET и @ Lasse :) –

1

Как насчет использования делегатов?

Action statement1 =() => button1.Visible = true; 
Action statement2 =() => button1.Text = "Number"; 
Смежные вопросы