c# - 如果我在以下 C# 场景中已经有了正确的类型,是否有办法避免 Cast<T>() ?

标签 c# linq

public class ItemStore {
    private Dictionary<Type, List<object>> _items = new Dictionary<Type, List<object>>();

    public void AddItem(object item) {
        var type = item.GetType();
        if (!_items.ContainsKey(type)) {
            _items[type] = new List<object>();
        }
        _items[type].Add(item);
    }

    public IEnumerable<T> GetItems<T>() {
        if(!_items.ContainsKey(typeof(T))) {
            return new List<T>();
        }
        return _items[typeof(T)].Cast<T>();
    }
}

(真实场景比较复杂,是多个项目使用的库,对具体类型一无所知....)

Cast<T>()GetItems()正在消耗相当多的时间。所以我宁愿避免它。有没有办法在 C# 中避免它 - 因为实际上列表已经包含正确的类型?

最佳答案

您需要稍微修改此类的内部结构,以便在项目查找中不使用泛型,因为我们需要存储列表的基础类型是正确的类型。这需要在创建列表时进行一些思考。我们还可以通过避免额外的查找来提高 AddItem 和 GetItems 的效率:

public class ItemStore {
    private Dictionary<Type, IList> _items = new Dictionary<Type, IList>();

    public void AddItem(object item) {
        var type = item.GetType();
        IList list;
        if (!_items.TryGetValue(type, out list)) {
            var listType = typeof(List<>).MakeGenericType(type);
            list = (IList)Activator.CreateInstance(listType);
            _items[type] = list;
        }

        list.Add(item);
    }

    public IEnumerable<T> GetItems<T>() {
        IList list;
        if(!_items.TryGetValue(typeof(T), out list)) {
            return Enumerable.Empty<T>();
        } else {
            return (IEnumerable<T>)list;
        }
    }
}

如果您可以修改 AddItem 的签名,这可能会更简单(无反射),但鉴于您已经说过这是一种过度简化,我将保持公共(public) API 不变。

关于c# - 如果我在以下 C# 场景中已经有了正确的类型,是否有办法避免 Cast<T>() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49328575/

相关文章:

c# - 如何正确地将 char * 从非托管 DLL 返回到 C#?

c# - 在登录中验证 EMAIL-MVC

c# - Linq 添加缺失的不同值

c# - 附加到表达式

c# - 更好的 Linq 查询,用于过滤没有子项的父列表

c# - 如何在 Realm 对象(更准确地说是 DateTime)中实现 Nullable 属性?

c# - 解析XML时如何访问节点的 'row'和 'column'

c# - 我将如何将以下 T-SQL 语句翻译成 Linq

c# - 使用 Lambda 获取不同的父项

c# - 根据一列获取两个数据表之间的差异