如果有以下classen
public interface ISomething { int Id { get; set; } }
public class SomethingA : ISomething {...}
public class SomethingB : ISomething {...}
在另一个课程中,我有以下两个列表:
List<SomethingA> aValues;
List<SomethingB> bValues;
我的问题是,是否有可能做这样的事情:
public List<ISomething> GetList(bool select) {
return select ? aValues : bValues;
}
我的目标是将其用作:
GetList(true).Single(x => x.Id) // or
foreach (var value in GetList(false))
{
value.Id = 18;
}
// anything else
更新: 我知道,有很好的可能性。但是还有一种方法可以实现以下目标吗?
GetList(true).Remove(myValue);
答案 0 :(得分:2)
您无法返回List<ISomething>
,因为List<T>
不是协变而类不能。 IEnumerable<T>
是协变的,您可以将其用作只读序列。
更改方法以返回IEnumerable<ISomething>
public static IEnumerable<ISomething> GetList(bool select)
{
return select ? (IEnumerable<ISomething>)aValues :bValues;
}
然后做
var result = GetList(true).Single(x => x.Id == 0);
foreach (var value in GetList(false))
{
value.Id = 18;
}
至于您的更新:如果您想要删除该项目,您需要失去一些灵活性。即使用非泛型IList
作为返回类型。
public static IList GetList(bool select)
{
return select ? (IList)aValues : bValues;
}
然后做
IList list = GetList(true);
foreach (var value in list.OfType<ISomething>())//OfType or Cast can be used
{
if (value.Id == 6)//Whatever condition
{
list.Remove(value);
break;
}
}
答案 1 :(得分:0)
最简单的解决方案可能是使用Linq Cast():
public List<ISomething> GetList(bool select)
{
return (List<ISomething>)(@select ? aValues.Cast<ISomething>() : bValues.Cast<ISomething>());
}
我知道,有很好的可能性。但是还有一种方法可以实现以下目标吗? 的GetList(真)卸下摆臂(myvalue的);
要从原始列表中删除,您可能最好使用其他人建议的类上的专门Remove方法,因为此处的大多数解决方案都会返回原始列表的副本。 您可以很容易地从列表副本中删除元素,但我知道这不是您所要求的。
var result = GetList(true);
result.Remove(myValue);
答案 2 :(得分:0)
我喜欢OfType
扩展程序,因为它会返回您需要的类型列表
var listA = initialList.OfType<TypeA>(); //return List<TypeA>
var listB = initialList.OfType<TypeB>(); //return List<TypeB>
所以在你的情况下,你从
开始var aValues = List<ISomething>.OfType<SomethingA>()
然后你可以迭代你需要的任何子集合。当然,您正在使用IEnumerable,但可以隐式转换回IEnumerable<ITest>
。
如果你想过滤掉值,我会创建显式方法来删除它们,但这取决于你最终需要实现的目标(例如比较Id而不是整个对象):
public IEnumerable<T> Remove<T>(this List<IDisposable> values, T valueToRemove) where T: IComparable
{
return values.OfType<T>().Where(t => valueToRemove.CompareTo(t) != 0);
}
答案 3 :(得分:-1)
您可以使用.Cast<T>
方法,如下所示:
if (select)
{
return aValues.Cast<ISomething>().ToList();
}
else
{
return bValues.Cast<ISomething>().ToList();
}
或将所有项目添加到commong Lis(),如下所示:
var ret = new List<ISomething>();
if (select)
{
ret.AddRange(aValues);
}
else
{
ret.AddRange(bValues);
}
return ret;
由于你只想迭代它,我会写这样的方法:
public IEnumerable<ISomething> GetList(bool select) {
return select ? aValues.Cast<ISomething>() : bValues.Cast<ISomething>();
}
您还可以查看此StackOverflow question。