将类对象转换为类索引

时间:2020-02-07 08:21:24

标签: c# class

Class Person {
  int Id 
  string Name 
  string Address 
  // etc 
}

而不是像Person.Id,Person.Name,Person.Address那样访问它。我想像Person ['Id'],Person ['Name']一样通过索引访问它。是否有为此的任何代码生成或linq转换。

5 个答案:

答案 0 :(得分:4)

您可以使用Json.NET的{​​{1}}类

JObject

答案 1 :(得分:2)

这是一个纯C#实现:

class Program
{
    static void Main(string[] args)
    {
        Person person = new Person
        {
            Id = 1,
            Name = "test",
            Address = "tost"
        };

        Console.WriteLine(person["Id"]);
        person["Id"] = 5;
        Console.WriteLine(person["Id"]);
    }
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }

    public object this[string propertyName]
    {
        get
        {
            return this.GetType().GetProperty(propertyName).GetValue(this);
        }

        set
        {
            this.GetType().GetProperty(propertyName).SetValue(this, value);
        }
    }
}

输出:

1

5

重要说明:

我永远不建议在生产环境中使用此功能,如果要使用手动实现的系统,则至少应处理类型和属性提取,以避免消耗过多的内存并超出开销。

答案 2 :(得分:0)

使用反射和索引器:

public class ExampleClass{

    public object this[string name]
    {
        get
        {
            var properties = typeof(ExampleClass)
                    .GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var property in properties)
            {
                if (property.Name == name && property.CanRead)
                    return property.GetValue(this, null);
            }

            throw new ArgumentException("Can't find property");

        }
        set {
            return;
        }
    }
}

答案 3 :(得分:0)

索引器不会使数据比较容易。我怀疑 real 问题是如何以与Python的DataFrames相同的方式在C#中处理数据。从.NET 1.0开始,ADO.NET提供了DataTable类。尽管它确实支持搜索,合并和区分之类的操作,但它对数据库处理的意义要大于数据分析。

对于数据分析,新的Microsoft.Data.Analysis包提供了DataFrame类。

也就是说,要按名称读取属性,必须使用反射(昂贵的操作)。使这种便宜的一种方法是缓存类型和属性描述符。不过,您可以使用Marc Gravel的FastMember库来做到这一点,而不是自己编写代码。这样,您可以创建TypeAccessor或ObjectAccessor类型并按名称读取属性,例如:

var wrapped = ObjectAccessor.Create(obj);
string propName = // something known only at runtime 
Console.WriteLine(wrapped[propName]);

如果要读取多个对象,则需要TypeAccessor:

var accessor = TypeAccessor.Create(type); 
string propName = // something known only at runtime 
while( /* some loop of data */ )
{ 
  accessor[obj, propName] = rowValue; 
}

图书馆不是那么大。如果您不允许使用NuGet软件包,则可以将代码复制到项目中。

答案 4 :(得分:-1)

如果需要将属性作为变量值访问,请查找反射。

ex) 字符串a =“名称”; 人[a]