在运行时之前不知道列表类型时添加到列表

本文关键字:列表 类型 添加 不知道 运行时 | 更新日期: 2023-09-27 17:57:50

我有一个接受object的方法。我知道这个对象是一个List<T>,但是当T被传递到方法中时,它可能在基类的子级之间随时发生变化。

因此,如果我的基类是MonthType,并且我有名为BlockMonthTypeAreaMonthType的子类,那么传入的对象可以是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中,并且知道它已添加到源对象中。

可能不是伊恩上面提到的那个主意,但他做到了。