簡體   English   中英

C# 非通用 ISet 接口

[英]C# Non-Generic ISet Interface

.NET 4.0引入了一個非泛型IList ,它公開了向 List 添加值的能力,而無需知道泛型類型。 這很有用,因為它允許我編寫如下方法:

void CreateListFromBytes(IntPtr bytes, Type outputType, out object outputObject)
{
    Type elementType = outputType.GenericTypeArguments[0];
    int numberOfElements = ReadHeaderBytes(bytes);
    bytes += Marshal.SizeOf(typeof(int));

    IList outputList = (IList) Activator.CreateInstance(outputType);
    for (int i = 0; i < numberOfElements; i++)
    {
        object element = ReadDataBytes(bytes, elementType);
        bytes += Marshal.SizeOf(elementType);
        outputList.Add(element);
    }

    outputObject = outputList;
}

但是,當我嘗試為HashSetISet實現一個具有類似樣式的方法時,我找不到這樣的非通用接口來公開和Add()方法。

我想知道是否存在我可能錯過的這樣的界面。 如果沒有,我想知道如何將元素添加到我確定是Set對象中(因為我創建了它Activator.CreateInstance()

我最終會得到幾個用於構建集合的輔助類型:

interface ISetBuilder 
{
    void Add(object item);
    object Build();
}

class SetBuilder<T, TSet> : ISetBuilder where TSet : ISet<T>, new() 
{
    private readonly TSet _set = new TSet();

    public void Add(object item) 
    {
        if (!(item is T typedItem)) 
        {
            throw new ArgumentException();
        }

        _set.Add(typedItem);
    }

    public object Build() => _set;
}

然后可以像這樣使用這些類型:

var builderType = typeof(SetBuilder<,>).MakeGenericType(elementType, outputType);
var builder = (ISetBuilder) Activator.CreateInstance(builderType);
var element = CreateElement(...);
builder.Add(element);
var set = builder.Build();

是的,這也可以推廣到支持列表。 只需將ISet<T>替換為ICollection<T>

另一種可能(但不太穩健)的解決方案是通過使用反射來查找和調用集合的特定Add方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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