执行存储在字符串变量中的 c# 语句

本文关键字:语句 变量 存储 字符串 执行 | 更新日期: 2023-09-27 18:33:13

我想执行一个存储在字符串变量中的 C# 语句。例如:

string statement1 = "button1.Visible = true";
string statement2 = "button1.Text = '"Number'"";

执行存储在字符串变量中的 c# 语句

查看您的评论,并且您有 80 个控件需要非常相似的操作,动态编译可能为此目的矫枉过正。可以使用父容器的集合Controls以及按钮的 Tag 属性来实现它。单个事件处理程序就足够了。

可以使用 LINQ 成员(如 OfTypeCast(使代码更小。

编辑

查看最新评论后,您应该做的是以编程方式创建按钮并将它们添加到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,然后将按钮添加到面板并在循环中设置它们的行/列属性。这将有助于更好地响应调整事件大小等。

从您的评论来看,您似乎只想迭代 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必须引用您的表单对象(拥有按钮的对象(。

使用委托怎么样?

Action statement1 = () => button1.Visible = true;
Action statement2 = () => button1.Text = "Number";