代码之家  ›  专栏  ›  技术社区  ›  JoelFan

无法缩短接口

  •  0
  • JoelFan  · 技术社区  · 15 年前

    我有这处房产,运转良好:

    public IEnumerable<IGrouping<MessageType, Message>> MessageGroups
    {
        get
        {
            return
                (from msg in _messages
                    orderby msg.Type descending
                    group msg by msg.Type);
        }
    }
    

    但是,这让我不得不重复那丑陋的样子 IEnumerable<IGrouping<MessageType, Message>> 在我的代码中有几个地方。我试图通过定义这样一个简单的包装器接口来让眼睛更容易看到:

    public interface IMessageGroups :
        IEnumerable<IGrouping<MessageType, Message>> { }
    

    并将上述属性更改为:

    public IMessageGroups MessageGroups
    {
        get
        {
            return
                (IMessageGroups)
                (from msg in _messages
                    orderby msg.Type descending
                    group msg by msg.Type);
        }
    }
    

    这构建得很好,但在运行时我得到:

    无法强制转换类型为的对象 'System.Linq.GroupedEnumerable'3[消息,消息类型,消息]' 键入“IMessageGroups”。

    (从错误消息中删除了项目特定的命名空间)

    我能做些什么来解决这个问题?

    4 回复  |  直到 15 年前
        1
  •  3
  •   Darin Dimitrov    15 年前

    你可以尝试使用 type alias :

    using Foo = IEnumerable<IGrouping<MessageType, Message>>;
    

    然后:

    public Foo MessageGroups
    {
        get
        {
            return
                (from msg in _messages
                 orderby msg.Type descending
                 group msg by msg.Type);
        }
    }
    

    另一种可能是进一步扩展您的LINQ查询和 选择 分组后创建的某些自定义类型:

    public IEnumerable<Foo> MessageGroups
    {
        get
        {
            return
                (from msg in _messages
                 orderby msg.Type descending
                 group msg by msg.Type
                 select new Foo { Messages = g, MessageType = g.Key }      
                );
        }
    }
    

    Foo:

    public class Foo
    {
        public MessageType MessageType { get; set; }
        public IEnumerable<Message> Messages { get; set; }
    }
    

    如果你不在乎懒惰的评价,你可以 .ToArray() 在LINQ查询的末尾,返回类型变为 Foo[] .

        2
  •  2
  •   Kirk Woll    15 年前

    它构建得很好,因为编译器永远无法确定返回的类型是否实际上不是实现接口的子类。(将其与类的强制转换进行比较,会得到一个编译错误,因为 静态已知。)

    但事实仍然是,您试图将LINQ表达式的结果强制转换为它不实现的接口(“包装器”接口)。这根本不起作用。除了声明一个自己实现它的类,并在实现中实际执行“包装”操作(可能将现有的LINQ表达式传递给构造函数),您不能真正地对其进行修复。

        3
  •  1
  •   Thomas Levesque    15 年前

    演员阵容 IMessageGroups 失败,因为查询结果是 IEnumerable<IGrouping<MessageType, Message>> ,不是的实例 间接组 . 但是你可以写一个 MessageGroups 类并使用它包装查询结果:

    public class MessageGroups : IMessageGroups
    {
        private readonly IEnumerable<IGrouping<MessageType, Message>> _groups;
    
        public MessageGroups(IEnumerable<IGrouping<MessageType, Message>> groups)
        {
            _groups = groups;
        }
    
        public IEnumerable<IGrouping<MessageType, Message>> GetEnumerator()
        {
            return _groups.GetEnumerator();
        }
    
        public static MessageGroups Create(IEnumerable<IGrouping<MessageType, Message>> groups)
        {
            return new MessageGroups(groups);
        }
    }
    

    像这样使用:

    public IMessageGroups MessageGroups
    {
        get
        {
            return
                MessageGroups.Create(
                    from msg in _messages
                    orderby msg.Type descending
                    group msg by msg.Type);
        }
    }
    
        4
  •  0
  •   Community Mohan Dere    8 年前

    在您的CS文件的顶部:

     using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;
    

    Source

    或者在您的情况下:

    using ShortName = IEnumerable<IGrouping<MessageType, Message>>;