首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >协变元组

协变元组
EN

Code Review用户
提问于 2013-11-18 15:01:06
回答 1查看 597关注 0票数 10

我在寻找一种将Tuple<List>放入Tuple<IEnumerable>的方法,我发现元组没有协方差。

  1. 是C# 4.0元组协变量
  2. 协/反方差?Tuple>对列表不满意

我决定自己实现一个接口,该接口将子类为一个元组,并支持协方差:

代码语言:javascript
复制
/// <summary>
/// A wrapper around Tuple for gaining covariance
/// </summary>
public static class ITuple
{
    private class _ITuple<T1> : Tuple<T1>, ITuple<T1> { public _ITuple(T1 item1) : base(item1) { } }
    public static ITuple<T1> Create<T1>(T1 item1) { return new _ITuple<T1>(item1); }

    private class _ITuple<T1, T2> : Tuple<T1, T2>, ITuple<T1, T2> { public _ITuple(T1 item1, T2 item2) : base(item1, item2) { } }
    public static ITuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) { return new _ITuple<T1, T2>(item1, item2); }

    private class _ITuple<T1, T2, T3> : Tuple<T1, T2, T3>, ITuple<T1, T2, T3> { public _ITuple(T1 item1, T2 item2, T3 item3) : base(item1, item2, item3) { } }
    public static ITuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) { return new _ITuple<T1, T2, T3>(item1, item2, item3); }
}

public interface ITuple<out T1> { T1 Item1 { get; } }
public interface ITuple<out T1, out T2> { T1 Item1 { get; } T2 Item2 { get; } }
public interface ITuple<out T1, out T2, out T3> { T1 Item1 { get; } T2 Item2 { get; } T3 Item3 { get; } }

一些测试和使用:

代码语言:javascript
复制
[TestMethod]
public void TestCompile()
{
    // no assertion, just test that the compilation work
    ITuple<Exception> item = ITuple.Create<NullReferenceException>(null);
    ITuple<IEnumerable<int>> item2 = ITuple.Create<List<int>>(null);
}
[TestMethod]
public void TestEqual()
{
    Assert.AreEqual(ITuple.Create(1, Tuple.Create("a")), ITuple.Create(1, Tuple.Create("a")));
    Assert.AreNotEqual(ITuple.Create(1, Tuple.Create("a")), ITuple.Create(1, Tuple.Create("b")));
}

我选择在静态类中隐藏具体类_ITuple的实现,因此您只能访问公共和静态构建器ITuple.Create

问题:

  1. 子类和相等支持子类元组很容易,没有什么可做的,这是我关心的问题。我遗漏了什么吗?我看不出为什么等式和hashcode在经典的Tuple中不能像预期的那样起作用,但是也许您会在我没有想到的地方找到一个问题。
  2. 命名约定
    • 与静态类Tuple包含所有Create静态方法一样,不是接口的ITuple具有静态构建器。在什么时候用I前缀命名一个非接口是很奇怪的呢?
    • 起初,我调用了ITuple接口ICovariantTuple,但是发现它太长了,框架中没有ITuple。很明显,ITuple是协变的吗?
EN

回答 1

Code Review用户

回答已采纳

发布于 2013-11-18 16:41:08

  1. 我认为非接口类型不应该被称为ISomething。您只需调用静态类Tuple,并使用不同的命名空间将其与System.Tuple区分开来。或者您可以将类称为TupleEx,尽管这并不是非常描述性的。但是最好的选择是,如果您能够为将它与System.Tuple区分开来的类型找出一个好名称。我同意CovariantTuple是相当长的,虽然我没有更好的想法。
  2. 我也不喜欢_ITuple这个名字,即使它不是公开可见的。我会把它叫做TupleImpl。(同样,如果你想出一个好名字,你也可以在这里用这个名字。)
  3. 关于平等:您的ITuples将显示与正常的Tuples相同的内容。这很可能是你想要的,但你应该意识到这一点。我认为平等或哈希码没有其他问题。
  4. 考虑不要把所有的东西都写在一行上。我想这会让代码更清晰。
  5. 添加一些方法将System.Tuple转换为ITuple和back可能是有意义的。
票数 7
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/35601

复制
相关文章

相似问题

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