有什么办法可以将类对象通用地传递给方法

时间:2019-11-07 19:22:29

标签: c# class generics

我有如下这样的类对象

       Value        Step     
f1     0.9842       3.795K

我正在将该类对象传递给如下所示的方法

public class Version
{

    [JsonIgnore]
    public  string ClassName = "Version";

    [JsonIgnore]
    public string Name { get; set; } = "Version 1";
    .......
    .......
}

我正在调用Add方法,如下所示

class EpJSON
{
    public Dictionary<string, Dictionary<string, object>> model = new Dictionary<string, Dictionary<string, object>>();

    public void Add(dynamic v)
    {
        if (model.ContainsKey(v.ClassName))
        {
            if (model[v.ClassName].ContainsKey(v.Name))
            {
                model[v.ClassName][v.Name] = v;
            }
            else
            {
                model[v.ClassName].Add(v.Name, v);
            }

        }
        else
        {
            Dictionary<string, object> obj = new Dictionary<string, object>() { { v.Name, v } };
            model.Add(v.ClassName, obj);
        }

    }

    public void Save(string path)
    {
        using (StreamWriter file = File.CreateText(path))
        {
            JsonSerializer serializer = new JsonSerializer();
            serializer.Serialize(file, model);
        }
    }

}

我想从你们那里得到建议,是否有任何通用的方法可以将var model = new EpJSON(); var ver1 = new Version() { VersionIdentifier = "9.2" }; model.Add(ver1); var ver2 = new Version() { Name = "V2", VersionIdentifier = "9.3" }; model.Add(ver2); model.Save(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.json")); 对象传递给方法Version,并且我可以传递与此完全相同的其他对象具有多余字段的对象

请让我知道是否需要更多信息

更新的代码

Add

2 个答案:

答案 0 :(得分:1)

通过通用我不确定您的意思。如果要动态调用EpJson类的Add方法,则可以使用Type类的GetMethod函数。这是使用List<string>的示例,但它肯定适用于任何类型:

var myList = new List<string>();
var addMethod = myList.GetType().GetMethod(nameof(myList.Add));
addMethod.Invoke(myList, new object[] { "hello" });

Console.WriteLine(String.Join(",", myList)); // produces "hello"

编辑:好的,我想我明白你的意思。您必须使用多态来实现此目的。假设您要传递具有ClassNameName属性的对象。然后,您可以定义一个接口,例如:

public interface IObjectWithRequiredProperties
{
    string ClassName { get; set; }
    string Name { get; set; }
}

然后通过将类定义更改为

,使您的Version类成为此接口的实现者
public class Version : IObjectWithRequiredProperties
...

这将强制该类包含您在接口上定义的那些属性。现在有趣的部分到了,您必须将Add方法更改为通用方法

public void Add<TGeneric>(TGeneric v) where TGeneric: IObjectWithRequiredProperties

现在,您可以确定传递给Add方法的任何内容都将具有IObjectWithRequiredProperties具有的所有属性。自然,您必须将基础字典更改为接口的类型。这称为generic type constraint

答案 1 :(得分:0)

我仍然会建议使用界面方式,但是如果您绝对想按照您的描述去做,那么dynamic关键字或反射就可以了

    public void Add(dynamic v)
    {
        Type type = v.GetType();

        bool hasClassNameProperty = type.GetProperty("ClassName") != null;
        if (hasClassNameProperty)
        {
            string className = v.ClassName;
        }

        bool hasNameProperty = type.GetProperty("Name") != null;
        if (hasNameProperty)
        {
            string name = v.Name;
        }
    }

    public void Add2(object o)
    {
        Type type = o.GetType();
        PropertyInfo classNameProperty = type.GetProperty("ClassName");
        if (classNameProperty != null)
        {
            string className = (string)classNameProperty.GetValue(o);
        }

        PropertyInfo nameProperty = type.GetProperty("Name");
        if (nameProperty != null)
        {
            string name = (string)nameProperty.GetValue(o);
        }
    }