【问题标题】:Accessing a variable using a string containing the variable's name [duplicate]使用包含变量名称的字符串访问变量[重复]
【发布时间】:2012-06-20 14:52:25
【问题描述】:

我正在从数据库中读取字符串变量的名称(例如“_datafile”)。我想知道如何使用这个字符串访问我的程序中的命名变量。

我已经尝试过使用字典、哈希表和 switch-case 语句,但我想让变量自行动态解析。这可能吗?

【问题讨论】:

  • 你的问题不清楚。你能显示一些代码吗?您如何使用 switch-case 语句和字典,动态解析是什么意思?
  • "_datafile" to become _datafile 是什么意思?
  • 这里是一个代码 sn-p 以及字典定义 while (rdr.Read()) { string step = rdr.GetString(rdr.GetOrdinal("Step"));字符串标签 = rdr.GetValue(rdr.GetOrdinal("Tag")).ToString();字符串值 = rdr.GetValue(rdr.GetOrdinal("Value")).ToString(); AddDataToWorkflow(步骤,标签,SearchDictionary(值)); }

标签: c# string variables reflection


【解决方案1】:

您的意思是要使用字段名称作为字符串来获取字段的值吗?

public class MyClass
{
    public string _datafile;

    public MyClass()
    {
        _datafile = "Hello";
    }

    public void PrintField()
    {
        var result = this.GetType().GetField("_datafile").GetValue(this); 
        Console.WriteLine(result); // will print Hello
    }
}

编辑:@Rick,回复您的评论:

public class MyClass
{
    public IEnumerable<string> _parameters = new[] { "Val1", "Val2", "Val3" };

    public void PrintField()
    {
        var parameters = this.GetType().GetField("_parameters").GetValue(this) as IEnumerable;

        // Prints:
        // Val1
        // Val2
        // Val3
        foreach(var item in parameters)
        {
            Console.WriteLine(item);
        }
    }
}

【讨论】:

  • 这是部分工作的公共静态字符串_dataFile;字符串值 = rdr.GetValue(rdr.GetOrdinal("Value")).ToString();字符串结果 = this.GetType().GetField(value, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public).GetValue(this).ToString();这适用于奇异变量,现在我必须让它与一个集合一起工作,例如:一个名为 _parameters 的数据集合,我希望解析 _parameters.From 等。
  • 以上编辑是否回答了您的问题?
【解决方案2】:

如果要根据字符串名称获取字段的值,则必须使用反射。

class MyClass
{
    public int DataFile { get; set; }

    public int _datafile;
}

var ob = new MyClass();
var typ = typeof(MyClass);
var f = typ.GetField("_datafile");
var prop = typ.GetProperty("DataFile");
var val = f.GetValue(ob);
var propVal = prop.GetValue(ob);

【讨论】:

  • 我认为这不会按原样工作。 _datafile 需要是一个属性。
  • 你应该能够对属性做同样的事情。我在示例中添加了一个。
  • 嗯,是的,它适用于DataFile,但不适用于_datafile。你应该删除var f = typ.GetField("_datafile");
  • 此代码在 LinqPad 中有效,但前提是该字段是公共的,所以我同意通常您不希望以这种方式访问​​字段。这取决于 OP 想要做什么。
  • 好吧我的错,我认为它只适用于属性而不适用于字段。但确实如此。
【解决方案3】:

通常你会创建一个类来表示一个表记录的值。如果您的表有一个 ID 一个 FirstName 和一个 LastName 列,您将创建一个这样的类

public class Person
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

然后你创建一个人员列表

var people = new List<Person>();

现在您可以将人员添加到列表中。

var p = new Person();
p.ID = 5;
p.FirstName = "John";
p.LastName = "Doe";
people.Add(p);

您可以使用 DataReader 从表中读取数据

string sql = "SELECT * FROM tblPerson WHERE LastName LIKE @pattern";
cmd = new SqlCommand(sql);
cmd.Connection = "server=test;uid=sa;pwd=manager;database=northwind";
cmd.Parameters.AddWithValue("@pattern", "A%"); // Names beginning with "A"
using (SqlDataReader reader = cmd.ExecuteReader()) {
    // Get column indexes
    int idOrdinal = reader.GetOrdinal("ID");
    int firstNameOrdinal = reader.GetOrdinal("FirstName");
    int lastNameOrdinal = reader.GetOrdinal("LastName");

    while(reader.Read()) {
        var p = new Person();
        p.ID = reader.GetInt32(idOrdinal);
        p.FirstName = reader.GetString(firstNameOrdinal);
        p.LastName = reader.GetString(lastNameOrdinal);
        people.Add(p);
    }
}

【讨论】:

  • 不是很清楚,但是我觉得这个问题其实是关于反射,而不是数据库访问……
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 2012-09-05
  • 1970-01-01
相关资源
最近更新 更多