简体   繁体   English

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

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

I have the following class example here: 我在这里有以下课程示例:

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,

        };
    }
}

Now, however, i want to set for example only Bar to a value in the Create method of the class if the propertyname is Bar . 但是,现在,如果属性名是Bar ,那么我想仅在类的Create方法中将例如Bar设置为一个值。 So i took a look at C# setting/getting the class properties by string name but i can't get this to work in the create method. 因此,我看了看C#设置/通过字符串名称获取类属性,但无法在create方法中使用它。 Same goes for Setting a property by reflection with a string value so i'm kinda lost here. 通过反射使用字符串值设置属性也是如此,所以我有点在这里迷失了方向。

As a small bit of clarification. 作为一点澄清。 I can get the above methods to work in the create, however not in the return which is where it needs to work. 我可以在创建中使用上述方法,但是不能在需要使用的返回中使用。

The solution below seems to work for us for now, however, i think it could be optimized. 下面的解决方案似乎目前对我们有用,但是,我认为可以对其进行优化。

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,
        };
    }
}

You can avoid reflection and keep everything simpler using a dictionary of Action s: 您可以使用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;
    }
}

With this approach, you can even change the property names, while keeping the configuration values the same. 使用这种方法,您甚至可以更改属性名称,同时保持配置值相同。 Depending upon the situation, it could be a huge advantage. 根据情况,这可能是一个巨大的优势。

Having said this, I feel that your requirement could probably be better answered with more context information and a slightly different design. 说了这么多,我觉得可以通过更多上下文信息和稍微不同的设计来更好地满足您的要求。 YMMV. YMMV。

It will work for you, but you still need to check if property is a valid property. 它将为您工作,但您仍然需要检查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;
}

Something looking like this should work for you, you could also use 看起来像这样的东西应该对您有用,您也可以使用

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

But you'll have to handle errors. 但是您必须处理错误。

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

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