我有如下这样的类对象
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
答案 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"
编辑:好的,我想我明白你的意思。您必须使用多态来实现此目的。假设您要传递具有ClassName
和Name
属性的对象。然后,您可以定义一个接口,例如:
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);
}
}