簡體   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