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类型操作。我正在尝试扩展它以添加一个新属性,我将研究显式实现接口,然后在类上创建良好的强泛型方法。