首页 > 解决方案 > C# 为包装数据列表实现 ICollection 接口

问题描述

我可以使用一些关于如何正确实现某些包装数据的接口的输入。

我有一个包含 List<T_wrapper> 的类。T_wrapper 是一个包含 T_key 和 T_value 类型的成员变量以及其他数据的类。

该实现类似于字典(始终按 T_key 排序,每个键最多 1 个条目),但为了论证,假设我不能使用字典,而 List<T_wrapper> 是我被迫使用的。我被一个包装类的列表和以下接口困住了。

我需要为类实现一个接口,该接口返回一个 ICollection<T_key> 而不创建一个全新的列表。真正的问题是:有没有办法从本质上“转发”包装类中的成员键,例如使用委托,而不是创建一个全新的列表?

这是我需要的一个简单示例:

public class MyCollection<T_key, T_value> : ICollection_requiring_interface
    where T_key : System.Enum
{
    public List<T_wrapper> DataList=
       new List<T_wrapper>();

    public class T_wrapper
    {
        public T_key Key;
        public T_value Value;
    }

    public ICollection<T_key> GetKeyCollection
    {
        get
        {
            return DataList. ???? => some way to forward T_wrapper.Key
        }
    }
}

我还是 C# 的新手,来自 C++ 背景,并且对接口、委托和迭代器仍然很模糊。我在网上搜了一下,发现了几种类似的方法,但不起作用。

恭敬地请不要提供替代方案,因为我目前坚持这一点。但是,我全心全意地接受我所问的事情是不可能的/对语言有根本的误解。

非常感谢建设性的反馈!

标签: c#collectionsinterfacedelegates

解决方案


主要答案:

我明白你想要什么。如果您的Wrapper 类中有其他信息,则可以通过以下方式实现:

        public interface IMyCollection<TKey>
        {
            ICollection<TKey> GetKeyCollection();
            //add some here or in class methods to edit the values or add them with key
        }

        public class Wrapper<TKey, TValue> where TKey : Enum
        {
            public TKey Key;
            public TValue Value;

            public Wrapper(TKey key)
            {
                Key = key;
                //and other things you need
            }
            
            public Wrapper(TKey key, TValue value)
            {
                Key = key;
                Value = value;
                //and other things you need
            }
        }
        
        public class MyCollection<TKey, TValue> : IMyCollection<TKey> where TKey : Enum
        {
            private ICollection<TKey> _keys = new List<TKey>();
            private ICollection<Wrapper<TKey, TValue>> _dataList = new List<Wrapper<TKey, TValue>>();

            public ICollection<Wrapper<TKey, TValue>> DataList
            {
                get
                {
                    var list = _dataList;
                    foreach (var key in _keys)
                    {
                        if (!list.Any(w => w.Key.Equals(key)))
                        {
                            _dataList.Add(new Wrapper<TKey, TValue>(key));
                        }
                    }

                    return list;
                }
            }

            public ICollection<TKey> GetKeyCollection()
            {
                return _keys;
            }
        }

以下行已弃用的答案:


您不需要实现自己的包装器。请改用 IDictionary,或者如果您需要更多功能而不是在包装类中实现它。请遵循泛型接口的命名约定。

这是您需要的:

using System;
using System.Collections.Generic;
using System.Linq;

namespace YourProjecy
{
    public interface IMyCollection<TKey>
    {
        ICollection<TKey> GetKeyCollection();
    }

    public class MyCollection<TKey, TValue> : IMyCollection<TKey> where TKey : System.Enum
    {
        public Dictionary<TKey, TValue> DataList = new();

        public ICollection<TKey> GetKeyCollection()
        {
            return DataList.Select(dl => dl.Key).ToList();
        }
    }
}

或者,如果您想参考要编辑的密钥集合,则可以在下面实现代码:

        public interface IMyCollection<TKey>
        {
            ICollection<TKey> GetKeyCollection();
            //add some here or in class methods to edit the values or add them with key
        }

        public class MyCollection<TKey, TValue> : IMyCollection<TKey> where TKey : System.Enum
        {
            private ICollection<TKey>  _keys = new List<TKey>();
            private IDictionary<TKey, TValue> _dataList = new Dictionary<TKey, TValue>();

            public IDictionary<TKey, TValue> DataList
            {
                get
                {
                    var dictionary = _dataList;
                    foreach (var key in _keys)
                    {
                        if (!dictionary.ContainsKey(key))
                        {
                            _dataList.Add(key, default);
                        }
                    }
                    return dictionary;
                }
            }
            public ICollection<TKey> GetKeyCollection()
            {
                return _keys;
            }
        }

推荐阅读