C# 在运行时才知道列表类型时添加到列表

C# 在运行时才知道列表类型时添加到列表,c#,generics,C#,Generics,我有一个接受对象的方法。我知道的这个对象是一个列表,但是在传递到方法中的任何时候,基类的子类之间的T可能会有所不同 因此,如果我的基类是MonthType,并且我有名为BlockMonthType和AreaMonthType的子类,则传入的对象可以是List或List中的任何一个 我想能够添加项目到这个对象,但当我投它似乎是一个副本,原始对象不更新 我这样做是为了演员: var objectList = ((IEnumerable<MonthType>)graphObject.Sou

我有一个接受
对象的方法。我知道的这个对象是一个
列表
,但是在传递到方法中的任何时候,基类的子类之间的T可能会有所不同

因此,如果我的基类是
MonthType
,并且我有名为
BlockMonthType
AreaMonthType
的子类,则传入的对象可以是
List或List
中的任何一个

我想能够添加项目到这个对象,但当我投它似乎是一个副本,原始对象不更新

我这样做是为了演员:

var objectList = ((IEnumerable<MonthType>)graphObject.Source.Object).ToList();
只要objectList添加了一个新对象,这种方法就有效。但是,原始变量没有更新,所以当我离开该方法时,它会回到原始状态。当传入时,我知道对象是一个列表,因为我可以在调试器中看到它

我有没有办法做到这一点

这里是我正在使用的方法的简化版本

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
}
公共遍历GraphResult写入(ObjectGraph graphObject)
{
var objectList=((IEnumerable)graphObject.Source.Object).ToList();
var newObject=(MonthType)Activator.CreateInstance(rule.ObjectType);
newObject.Month=规则.Month;
objectList.Add(newObject);
//其他事情也做得很好,但这是关键
}
希望这能给它更多的上下文。该方法用于尝试和导航具有多种类类型的大型对象树。我正在尝试添加一个新的类类型处理程序,它将处理从列表中添加和删除项

// 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);
    }
}
//这在递归方法中用于循环对象的属性树
// .. 这里有更多代码
//其中属性是一个列表
foreach(属性中的var pInfo)
{
if(IsList(pInfo.PropertyType))
{
变量enumerable=(IEnumerable)pInfo.GetValue(currentObjectGraph.Source.Object,null);
var sourceEnumerator=enumerable.GetEnumerator();
var-graph=newObjectGraph(可枚举,pInfo.Name);
//这一部分由多个部分组成,但本质上代码查找可以处理此问题的对象列表
//然后调用该对象上的write方法
var something=GetInterfaceHandlerForObject(可枚举);
写(图表);
}
}

您应该使您的方法具有通用性:

public void MyMethod<T>(List<T> objectList) where T:class, new()
{
    objectList.Add(new T());
    ...
}
public void MyMethod(List objectList),其中T:class,new()
{
Add(newt());
...
}
使用泛型时很少需要强制转换。此外,您的ToList()会导致创建列表的新副本


这种方法的一个缺点是
T
需要有一个空构造函数。如果需要使用参数构造对象,可以改为传入
Func
。然后,您可以通过lambda表达式调用它,如:
(x)=>newblockmonthtype(someParameter,或其他)

您应该使您的方法通用:

public void MyMethod<T>(List<T> objectList) where T:class, new()
{
    objectList.Add(new T());
    ...
}
public void MyMethod(List objectList),其中T:class,new()
{
Add(newt());
...
}
使用泛型时很少需要强制转换。此外,您的ToList()会导致创建列表的新副本


这种方法的一个缺点是
T
需要有一个空构造函数。如果需要使用参数构造对象,可以改为传入
Func
。然后,您可以通过传入lambda表达式调用它,如:
(x)=>new BlockMonthType(someParameter,或其他)

我最终解决了这个问题,将底层列表T类型存储在ObjectGraph对象中,并在需要时转换为该类型

var objectList = ((IEnumerable)graphObject.Source.Object).Cast(monthAllocationRule.ListType);
如果没有正确的强制转换,objectList要么为null,要么是列表的副本。现在我可以添加到objectList,并知道它已添加到源对象


可能不是Ian上面提到的想法,但我做到了。

我最终解决了这个问题,将底层列表T类型存储在ObjectGraph对象中,并在需要时转换为该列表

var objectList = ((IEnumerable)graphObject.Source.Object).Cast(monthAllocationRule.ListType);
如果没有正确的强制转换,objectList要么为null,要么是列表的副本。现在我可以添加到objectList,并知道它已添加到源对象


可能没有Ian提到的想法,但成功了。

我不能让它成为通用的,因为它是一个接口的实现,接口声明它接受一个对象。然后你可以编写一些笨拙的代码来打开类型,并将对象强制转换为
列表
列表
。但是为什么你不能修复这个接口,谁写了这么糟糕的接口?你能发布更多的代码,尤其是接口吗?查看objectList的来源可能会有所帮助。@Ian谢谢。我想是的,如果那是唯一的办法。这是我继承的代码,用于递归对象属性搜索和do stuff类型操作。我正在尝试扩展它以添加一个新属性。我将考虑显式实现接口,然后在类上创建良好的强泛型方法。我不能将其泛型化,因为它是接口的实现,接口将其声明为接受对象。然后,您还可以编写一些笨拙的代码来切换类型和属性将对象强制转换为
列表
列表
。但是为什么你不能修复这个接口,谁写了这么糟糕的接口?你能发布更多的代码,尤其是接口吗?查看objectList的来源可能会有所帮助。@Ian谢谢。我想是的,如果那是唯一的办法。这是我继承的代码,用于递归对象属性搜索和do stuff类型操作。我正在尝试扩展它以添加一个新属性,我将研究显式实现接口,然后在类上创建良好的强泛型方法。