簡體   English   中英

如何在 C# 中創建一個可以包含 int 或 string 數組的 List 變量?

[英]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實現只是為了滿足集合初始化模式。 如果調用它們就會拋出,期望消費者會調用GetIntegerSizesGetStringSizes

這是代碼:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM