我正在尝试使用反射将一个新的Officer类实例添加到一个可能为空的列表中。
这些是我的课程
public class Report(){
public virtual ICollection<Officer> Officer { get; set; }
}
public class Officer(){
public string Name{ get; set; }
}
简化的代码段:
Report report = new Report()
PropertyInfo propertyInfo = report.GetType().GetProperty("Officer");
object entity = propertyInfo.GetValue(report, null);
if (entity == null)
{
//Gets the inner type of the list - the Officer class
Type type = propertyInfo.PropertyType.GetGenericArguments()[0];
var listType = typeof(List<>);
var constructedListType = listType.MakeGenericType(type);
entity = Activator.CreateInstance(constructedListType);
}
//The entity is now List<Officer> and is either just created or contains a list of
//Officers
//I want to check how many officers are in the list and if there are none, insert one
//Pseudo code:
if (entity.count = 0)
{
entity.add(new instance of type)
}
非常感谢!
答案 0 :(得分:1)
使用:
object o = Activator.CreateInstance(type); // "type" is the same variable you got a few lines above
((IList)entity).add(o);
答案 1 :(得分:1)
您有两种选择:
1)使用动态:
dynamic list = entity;
if (list.Count = 0)
{
list.Add(new instance of type)
}
2)使用反思:
var countProp = entity.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).First(p => p.Name == "Count");
var count = (int)countProp.GetValue(entity,null);
if(count == 0)
{
var method = entity.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public).First(m => m.Name == "Add");
method.Invoke(entity,new instance of type);
}
答案 2 :(得分:1)
这不是你要求的,但可以完成同样的任务。
public static ICollection<T> EnsureListExistsAndHasAtLeastOneItem(ICollection<T> source)
where T : Officer, new()
{
var list = source ?? new List<T>();
if( list.Count == 0 ) list.Add(new T());
return list;
}
如果Officer
没有默认构造函数,那么您可以添加工厂回调
public static ICollection<T> EnsureListExistsAndHasAtLeastOneItem
(ICollection<T> source, Func<T> builder)
where T : Officer
{
var list = source ?? new List<T>();
if( list.Count == 0 ) list.Add(builder());
return list;
}
答案 3 :(得分:0)
只需将您的实体恰当地命名为List<Officer>
(或更合适的抽象类型(例如IList
))并正常使用:
entity = Activator.CreateInstance(constructedListType) as IList;
但无需检查是否插入,只需插入:
entity.Insert(0, officer);
我假设(基于您已经知道如何使用反射创建实例的事实),您在创建Officer
类型的实例时没有遇到任何问题。
答案 4 :(得分:0)
重新阅读您的问题后进行编辑:这不是直接回答您的问题,而是建议采用不同的实施方式。
您可以轻松使用反射:
public class TestContainer<T>
{
private readonly List<T> _list;
public TestContainer()
{
_list = new List<T>();
}
public void Add()
{
_list.Add(default(T));
}
}
然后呼叫例如:
var t = new TestContainer<YourClass>();
t.Add();
t.Add();
t.Add();
您将按默认值
列出3个YourClass实例的列表