首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#非通用ISet接口

C#非通用ISet接口
EN

Stack Overflow用户
提问于 2019-04-18 01:06:41
回答 1查看 641关注 0票数 2

.NET 4.0引入了一个非泛型IList,它公开了向列表添加值的能力,而不需要知道泛型类型。这很有用,因为它允许我编写如下所示的方法:

代码语言:javascript
运行
复制
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())

EN

Stack Overflow用户

回答已采纳

发布于 2019-04-18 02:42:54

我最终会得到几个aux类型来构造一个集合:

代码语言:javascript
运行
复制
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;
}

然后可以像这样使用这些类型:

代码语言:javascript
运行
复制
var builderType = typeof(SetBuilder<,>).MakeGenericType(elementType, outputType);
var builder = (ISetBuilder) Activator.CreateInstance(builderType);
var element = CreateElement(...);
builder.Add(element);
var set = builder.Build();

是的,这也可以推广到支持列表。只需用ICollection<T>替换ISet<T>即可。

另一种可能的解决方案(但不太健壮)就是通过使用反射来查找和调用集合的特定Add方法。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55732764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档