我想獲得所有(唯一的)Apple(或Oranges)物件的串列:
var theBigFruitsList = new List<Fruits>{
new Fruits(){
Apples = new List<Apple>{
new Apple { Id = 1 },
new Apple { Id = 2 }
}
},
Oranges = new List<Orange>{
new Orange { Id = 4 },
new Orange { Id = 5 }
}
},
FruitBoolean = False,
FruitCount = 4,
},
new Fruits(){
Apples = new List<Apple>{
new Apple { Id = 3 },
new Apple { Id = 1 },
}
},
Oranges = new List<Orange>{
new Orange { Id = 6 },
}
}
FruitBoolean = False,
FruitCount = 3,
}
}
我已經為它撰寫了這個方法:
public static List<Apple> GetApplesFromBigFruitsList(List<Fruits> theBigFruitsList )
{
var dc = new Dictionary<long, Apple>();
foreach (var fruits in theBigFruitsList)
{
foreach (var apple in fruits.Apples)
{
if (!dc.ContainsKey(apple.Id))
dc.Add(apple.Id, apple);
}
}
return dc.Values.ToList();
}
但是,除了 Apples 和 Oranges 之外,該物件中還有許多其他型別的“Fruits”,我使用該方法超過 10 次,其中 Apple 一詞僅被替換為 Orange .. 使其通用化是有意義的。
我寫了這個函式,但它給出了一個錯誤,因為 Fruits 類沒有實作列舉器。請幫忙!
public static List<T> FilterFruits<T>(T typeToGet, List<Fruits> theBigFruitsList)
{
List<T> fruitResult = new List<T>();
var fruitType = typeToGet.GetType();
foreach (var fruits in theBigFruitsList)
{
foreach (var fruit in fruits) //errors, intention is to loop over all properties in the Fruits entity to find one specific type
if (fruit.GetType() == fruitType) //check if type is Apple
{
fruitResult.AddRange(fruits); //add the Apples to a list
}
}
return fruitResult;
}
課程:
public class Fruits{
public List<Apple> Apples { get; set; }
public List<Orange> Oranges { get; set; }
public List<Pineapple> Pineapples { get; set; }
public List<Mango> Mangos { get; set; }
public bool FruitBoolean { get; set; }
public long FruitCount { get; set; }
}
public class Apple{
public long Id { get; set; }
}
public class Orange{
public long Id { get; set; }
}
public class Pineapple{
public long Id { get; set; }
}
public class Mango{
public long Id { get; set; }
}
所需的方法結果:
var Apples = List<Apple>{
new Apple { Id = 1 },
new Apple { Id = 2 },
new Apple { Id = 3 }
}
uj5u.com熱心網友回復:
一份大名單
將每種型別的水果存盤在單獨的串列中是......很奇怪。我建議您將它們組合在一個串列中。如果你不能改變設計,你可以在運行時像這樣組合它們:
IEnumerable<object> GetAllFruits(Fruits bigFruitlist)
{
return ((IEnumerable<object>)bigFruitlist.Apples)
.Concat((IEnumerable<object>)bigFruitlist.Oranges)
.Concat((IEnumerable<object>)bigFruitlist.Mangoes)
.Concat((IEnumerable<object>)bigFruitlist.Pineapples);
}
當然,如果您的所有水果都有一個通用的界面會更好IEnumerable<object>——那么您就不需要——但是如果您也不能進行更改,這仍然可以作業。
一旦你有了組合串列,剩下的就很簡單了:
List<T> FilterFruits<T>(Fruits bigFruitlist)
{
return GetAllFruits(bigFruitList).OfType<T>().ToList();
}
使用一系列串列
如果出于某種原因您想避免列舉所有串列(即串列很大并且性能是一個問題),您也可以使用串列陣列來完成。
object[] GetAllFruitLists(Fruits bigFruitlist)
{
return new object[]
{
bigFruitlist.Apples,
bigFruitlist.Oranges,
bigFruitlist.Mangoes,
bigFruitlist.Pineapples
};
}
List<T> FilterFruits<T>(Fruits bigFruitlist)
{
return GetAllFruitLists(bigFruitList).OfType<List<T>>().Single();
}
uj5u.com熱心網友回復:
要在運行時查詢物件的型別,請使用反射。像這樣:
public static List<T> FilterFruits<T>(List<Fruits> fruitsList) where T : IFruit
{
List<T> fruitResult = new List<T>();
var fruitType = typeof(T);
foreach (var fruits in fruitsList)
{
foreach (var fp in typeof(Fruits).GetProperties())
{
if (fp.PropertyType == typeof(List<T>)) //check if type is Apple
{
fruitResult.AddRange((List<T>)(object)fp.GetValue(fruits)); //add the Apples to a list
}
}
}
return fruitResult;
}
(T)(object)o 是用于執行編譯器無法驗證的強制轉換的 C# 習慣用法,并且可能在運行時失敗,我們知道它不會,但編譯器不能,因為它不理解反射。
要在沒有反射的情況下執行此操作(在某些情況下可能太慢),您可以執行以下操作:
public static List<T> GetDistinct<T>( IEnumerable<Fruits> fruitsList) where T : IFruit
{
var ft = typeof(T);
Func<Fruits, List<T>> picker;
if (ft == typeof(Apple))
{
picker = (fruits) => (List<T>)(object)fruits.Apples;
}
else if (ft == typeof(Mango))
{
picker = (fruits) => (List<T>)(object)fruits.Mangos;
}
else
{
throw new NotImplementedException($"Fruit Type {ft.Name} not supported");
}
var rv = new Dictionary<long, T>();
foreach (var t in fruitsList.SelectMany(picker))
{
if (!rv.ContainsKey(t.Id))
{
rv.Add(t.Id, t);
}
}
return rv.Values.ToList();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/398324.html
