gpt4 book ai didi

c#-4.0 - 如何将类的属性转换为参数?

转载 作者:行者123 更新时间:2023-12-01 02:33:26 24 4
gpt4 key购买 nike

背景

我正在使用 Microsoft Dynamics CRM 2011 QueryExpressions,对于所有非 CRM 人员,我只知道我正在使用 SDK 来访问一个数据库,该数据库需要您输入您选择的列的字符串名称在自定义 ColumnSet 类中:

new ColumnSet("personid", "name", "age");

SDK 确实生成了早期绑定(bind)类,所以我确实有所有数据库表的类,并且早期绑定(bind)类都有一个字典,其键是已在对象上填充的表的列。 IE:
var p = new Person { Name = "John", Age = 39, SSN = null };
p.Attributes.Count == 3;
// p.Attributes.Keys == { "name", "age", "ssn" };

问题

填充 ColumnSet 时遇到三个问题
  • 我忘记了类/表包含哪些列
  • 我在某些列上加粗,直到运行时才出现错误
  • 实例化 ColumnSet 时,列名称都必须小写,这会导致可读性差,即 thissillyexampleisntthatreadable对比 ThisSillyExampleIsntThatReadable

  • 所有这三个问题都可以通过早期绑定(bind)来解决。

    我知道我可以为每个包含类的所有列的类创建一个枚举或结构,即:new ColumnSet(PersonColumns.PersonId, PersonColumns.Name, PersonColumns.Age),但我希望它使用已经生成的类.

    我最好的尝试

    我目前能想到的最好的是:
    ColumnSetFactory.Create<Person>(p => p.PersonId = null, p.Name = null, p.Age = null);

    Create 接受 T 类型的对象(本例中为 person),然后检查对象的字典以生成并返回 ColumnSet。

    目标

    有一个利用早期绑定(bind)类生成 ColumnSet 的通用函数:
    ColumnSetFactory.Create<Person>(p => p.PersonId, p.Name, p.Age);

    有任何想法吗?

    最佳答案

    不幸的是,您的尝试/目标语法在 C# 中不起作用,但您可能会得到一些接近它的东西。

    我不熟悉动态 crm,所以我做出这个假设,ColumnSet 的构造函数接受可变数量的字符串参数并具有签名:

    public ColumnSet(params string[] arguments)

    您可以创建一个返回对象初始值设定项(以创建匿名对象)的 lambda 表达式,并使用一些反射来使用初始值设定项的成员绑定(bind)调用构造函数。如果我了解您要完成的工作,您希望使用对象的现有参数名称实质上将这些名称传递给此构造函数以创建对象。

    您可以这样做:
    public static ColumnSet Create<T>(Expression<Func<T, object>> parameters)
    {
    var initializer = parameters.Body as NewExpression;
    if (initializer == null || initializer.Members == null)
    throw new ArgumentException("lambda must return an object initializer");
    var memberNames = initializer.Members
    .Select(member => member.Name.ToLower())
    .ToArray();
    var ctor = typeof(ColumnSet).GetConstructor(new Type[] { typeof(string[]) });
    return (ColumnSet)ctor.Invoke(new object[] { memberNames });
    }

    然后使用它,这样调用它:
    ColumnSetFactory.Create<Person>(p => new { p.PersonId, p.Name, p.Age });

    // Personally I prefer to call it like this to let the compiler
    // infer the generic arguments
    ColumnSetFactory.Create((Person p) => new { p.PersonId, p.Name, p.Age });

    这将生成对构造函数的等效调用:
    new ColumnSet("personid", "name", "age");

    您甚至可以组成列名并给它们随机值,这些值本身不会被使用,只是成员的名称。
    ColumnSetFactory.Create<Person>(p => new
    {
    p.PersonId,
    p.Name,
    p.Age,
    Foobar = 0,
    Boo = "rawr!!!",
    });

    这将生成对构造函数的等效调用:
    new ColumnSet("personid", "name", "age", "foobar", "boo");

    关于c#-4.0 - 如何将类的属性转换为参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11724058/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com