[英]How to create a List variable that can contain array of int or string in C#?
如何在 C# 中創建一個可以包含 int 或 string 數組的 List 變量?
我有一堂課:
public class GoogleAdSlot
{
public IList<int[]> Size { get; set; }
}
我如何創建一個列表,這樣
return new GoogleAdData
{
AdSlots = new Dictionary<string, GoogleAdSlot>
{
{
"googleAdSquareTile1",
new GoogleAdSlot {
Size = new List<int[]>
{
new[] {250, 250},
new[] {300, 300},
}
}
}
}
};
和:
return new GoogleAdData
{
AdSlots = new Dictionary<string, GoogleAdSlot>
{
{
"googleAdSquareTile1",
new GoogleAdSlot {
Size = new List<int[]>
{
new[] {fluid},
}
}
}
}
};
都是有效的。
您只能將一個 Type 及其派生類型存儲在泛型 List 中,在您描述的情況下,您必須使用List<object>
或者它的非泛型對應物ArrayList
,但不推薦使用非泛型集合並且不支持更新LINQ 等功能。
所以這看起來像:
var list = new List<object> {"lol", 101};
foreach (var value in list)
{
if(value is string s)
Console.WriteLine(s);
if (value is int i)
Console.WriteLine(i);
}
樣品在這里
List<object> lst = new List<object>() { "12",1,"apple"};
lst.ForEach(m => { Console.WriteLine((m is int) ? "int Varible" : "String Varibale"); });
我仍然不確定您的要求是什么,但這是最一般情況的解決方案。
第一的
創建一個能夠保存整數或字符串(但不能同時包含兩者)集合的類。 請注意,它使用集合初始化模式(兩次)(請參閱https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers )
請注意,各種GetEnumerator
實現只是為了滿足集合初始化模式。 如果調用它們就會拋出,期望消費者會調用GetIntegerSizes
或GetStringSizes
。
這是代碼:
public class AdSlotSizes : IEnumerable<int>, IEnumerable<string>
{
public enum CollectionType
{
Uninitialized,
Integers,
Strings,
}
private List<int> _integerSizes;
private List<string> _stringSizes;
public void Add(int sizeToAdd)
{
InitializeList(CollectionType.Integers);
_integerSizes.Add(sizeToAdd);
}
public void Add(string sizeToAdd)
{
InitializeList(CollectionType.Strings);
_stringSizes.Add(sizeToAdd);
}
public CollectionType SizesCollectionType => _collectionType;
private CollectionType _collectionType = CollectionType.Uninitialized;
private void InitializeList(CollectionType forCollectionType)
{
CollectionType oppositeCollectionType = (CollectionType)(((int) CollectionType.Strings + 1) - (int) forCollectionType);
if (_collectionType == oppositeCollectionType)
{
throw new ArgumentException($"A single {nameof(AdSlotSizes)} instance can only hold one type of sizes (int or string)");
}
if (_collectionType != CollectionType.Uninitialized)
{
return;
}
_collectionType = forCollectionType;
if (forCollectionType == CollectionType.Strings)
{
_stringSizes = _stringSizes ?? new List<string>();
}
if (forCollectionType == CollectionType.Integers)
{
_integerSizes = _integerSizes ?? new List<int>();
}
}
public IEnumerable<int> GetIntegerSizes()
{
if (_collectionType != CollectionType.Integers)
{
throw new ArgumentException("Size collection not initialized for integers");
}
foreach (var size in _integerSizes)
{
yield return size;
}
}
public IEnumerable<string> GetStringSizes()
{
if (_collectionType != CollectionType.Strings)
{
throw new ArgumentException("Size collection not initialized for strings");
}
foreach (var size in _stringSizes)
{
yield return size;
}
}
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
第二
現在我創建了一個集合AdSlotSizes
實例的類(同樣,使用集合初始化模式)。 它還實現了一個索引屬性( public AdSlotSizes this[int index]
),允許消費者索引到集合中:
public class GoogleAddSlot : IEnumerable<AdSlotSizes>
{
private readonly List<AdSlotSizes> _slotSizes = new List<AdSlotSizes>();
public void Add(AdSlotSizes sizes)
{
_slotSizes.Add(sizes);
}
public AdSlotSizes this[int index] => _slotSizes[index];
public IEnumerator<AdSlotSizes> GetEnumerator()
{
foreach (var sizes in _slotSizes)
{
yield return sizes;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator < AdSlotSizes > )this.GetEnumerator();
}
}
最后,一個測試方法:
public static void TestCollectionSizes()
{
var slot = new GoogleAddSlot
{
{new AdSlotSizes {200, 300, 400} },
{new AdSlotSizes {"fluid", "solid"}},
};
foreach (int size in slot[0].GetIntegerSizes())
{
Debug.WriteLine($"Integer Size: {size}");
}
foreach (string size in slot[1].GetStringSizes())
{
Debug.WriteLine($"String Size: {size}");
}
}
運行時,此測試方法輸出:
Integer Size: 200
Integer Size: 300
Integer Size: 400
String Size: fluid
String Size: solid
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.