在运行时之前不知道列表类型时添加到列表
本文关键字:列表 类型 添加 不知道 运行时 | 更新日期: 2023-09-27 17:57:50
我有一个接受object
的方法。我知道这个对象是一个List<T>
,但是当T被传递到方法中时,它可能在基类的子级之间随时发生变化。
因此,如果我的基类是MonthType
,并且我有名为BlockMonthType
和AreaMonthType
的子类,那么传入的对象可以是List<BlockMonthType> or List<AreaMonthType>
中的任何一个。
我希望能够向这个对象添加项目,但是当我投射它时,它似乎是一个副本,并且原始对象没有更新。
我这样做是为了铸造:
var objectList = ((IEnumerable<MonthType>)graphObject.Source.Object).ToList();
现在我想创建一个新项目并将其添加到列表中
// where ObjectType is a Type variable containing BlockMonthType
var newObject = (BlockMonthType)Activator.CreateInstance(graphObject.Source.ObjectType);
objectList.Add(newObject);
// and carry on the world is good
只要objectList添加了一个新的Object,这就行了。然而,原始变量没有更新,所以当我离开该方法时,它会返回到原始状态。我知道该对象是List<>当传入时,我可以在调试器中看到它。
我有什么办法可以做到这一点吗?
这是我在中使用的方法的精简版
public TraverseGraphResult Write(ObjectGraph graphObject)
{
var objectList = ((IEnumerable<MonthType>)graphObject.Source.Object).ToList();
var newObject = (MonthType)Activator.CreateInstance(rule.ObjectType);
newObject.Month = rule.Month;
objectList.Add(newObject);
// Other stuff as well is done but that's the crux of it
}
希望这能给它更多的上下文。该方法正被用于尝试和导航具有许多类类型的大型对象树。我正在尝试添加一个新的类类型处理程序,它将处理从列表中添加和删除项。
// This is being used in a recursive method to loop down a object's property tree
// .. more code here
// where properties is a List<PropertyInfo>
foreach (var pInfo in properties)
{
if (IsList(pInfo.PropertyType))
{
var enumerable = (IEnumerable)pInfo.GetValue(currentObjectGraph.Source.Object, null);
var sourceEnumerator = enumerable.GetEnumerator();
var graph = new ObjectGraph(enumerable, pInfo.Name);
// this part is made up but essentially the code looks up a list of objects that can deal with this
// particular one and returns it. We then call the write method on that object
var something = GetInterfaceHandlerForObject(enumerable);
something.Write(graph);
}
}
您应该使您的方法通用:
public void MyMethod<T>(List<T> objectList) where T:class, new()
{
objectList.Add(new T());
...
}
当您使用泛型时,很少需要强制转换。此外,ToList()会导致创建列表的新副本。
这种方法的一个缺点是T
需要有一个空的构造函数。如果需要使用参数构造对象,则可以传入Func<T>
。然后,您可以调用它传递lambda表达式,如:(x) => new BlockMonthType(someParameter, orAnother)
。
我最终通过将底层List T类型存储在ObjectGraph对象中并在需要时转换为该类型来解决此问题。
var objectList = ((IEnumerable)graphObject.Source.Object).Cast(monthAllocationRule.ListType);
没有正确的强制转换objectList为null或列表的副本。现在我可以添加到objectList中,并且知道它已添加到源对象中。
可能不是伊恩上面提到的那个主意,但他做到了。