繁体   English   中英

C#在创建中通过字符串名称设置类属性

[英]C# setting class properties by string name in create

我在这里有以下课程示例:

public class Foo
{
    public int Id { get; set; }

    public string Bar { get; set; }
    public string FooBar { get; set; }
    public string Fizz { get; set; }
    public string Buzz { get; set; }

    public static Foo Create(int id, string property, string value)
    {
        return new Foo
        {
            Id = id,

        };
    }
}

但是,现在,如果属性名是Bar ,那么我想仅在类的Create方法中将例如Bar设置为一个值。 因此,我看了看C#设置/通过字符串名称获取类属性,但无法在create方法中使用它。 通过反射使用字符串值设置属性也是如此,所以我有点在这里迷失了方向。

作为一点澄清。 我可以在创建中使用上述方法,但是不能在需要使用的返回中使用。

下面的解决方案似乎目前对我们有用,但是,我认为可以对其进行优化。

public class Foo
{
    public int Id { get; set; }

    public string Bar { get; set; }
    public string FooBar { get; set; }
    public string Fizz { get; set; }
    public string Buzz { get; set; }

    public static Foo Create(int id, string property, string value)
    {
        return new Foo
        {
            WebshopCustomerId = webshopCustomerId,
            Bar = (typeof(Foo)).GetProperty(property).Name == "Bar" ? value : null,
            FooBar = (typeof(Foo)).GetProperty(property).Name == "FooBar" ? value : null,
            Fizz = (typeof(Foo)).GetProperty(property).Name == "Fizz" ? value : null,
            Buzz = (typeof(Foo)).GetProperty(property).Name == "Buzz" ? value : null,
        };
    }
}

您可以使用Action字典避免反射并简化所有Action

public class Foo
{
    public int Id { get; set; }

    public string Bar { get; set; }
    public string FooBar { get; set; }
    public string Fizz { get; set; }
    public string Buzz { get; set; }

    private static Dictionary<string, Action<Foo, string>> _propertySetters =
        new Dictionary<string, Action<Foo, string>>()
        {
            { "Bar", (foo, value) => foo.Bar = value },
            { "FooBar", (foo, value) => foo.FooBar = value },
            { "Fizz", (foo, value) => foo.Fizz = value },
            { "Buzz", (foo, value) => foo.Buzz = value },
        };

    public static Foo CreateWithProperty(int id, string property, string value)
    {
        if (String.IsNullOrEmpty(property) || !_propertySetters.ContainsKey(property))
            throw new ArgumentException("property");

        var instance = new Foo { Id = id };

        var setter = _propertySetters[property];

        setter(instance, value);

        return instance;
    }
}

使用这种方法,您甚至可以更改属性名称,同时保持配置值相同。 根据情况,这可能是一个巨大的优势。

说了这么多,我觉得可以通过更多上下文信息和稍微不同的设计来更好地满足您的要求。 YMMV。

它将为您工作,但您仍然需要检查property是否为有效的属性。

       public static Foo Create(int id, string property, string value)
       {
           Foo foo = new Foo() { Id = id };

           PropertyInfo propertyInfo = foo.GetType().GetProperty(property);
           propertyInfo.SetValue(foo, Convert.ChangeType(value, propertyInfo.PropertyType), null);
           return foo;
       }
public static Foo Create(int id, string property, string value)
{
    Foo ret = new Foo
    {
        Id = id
    };
    foreach (FieldInfo element in typeof(Foo).GetFields())
        if (element.Name == property)
            element.SetValue(ret, value);
    foreach (PropertyInfo element in typeof(Foo).GetProperties())
        if (element.Name == property)
            element.SetValue(ret, value);
    return ret;
}

看起来像这样的东西应该对您有用,您也可以使用

ret.GetType().GetProperty(property).SetValue(ret, value);
ret.GetType().GetField(property).SetValue(ret, value);

但是您必须处理错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM