协变类型参数可以在构造函数的输入位置吗?

时间:2016-08-21 07:22:59

标签: c# .net kotlin covariance

this answer中,Michael建议将通用类型参数设为共变量,以便允许创建空节点。

我得到泛型类型参数在所有输出位置,因为Tree<T>及其子类型的所有属性都是只读的(val)。

确实在构造函数的输入位置有type参数。

我认为该代码在C#中不起作用所以我试了一下,令我惊讶的是,它运行得很好。

// See this: https://stackoverflow.com/questions/36753579/algebraic-data-types-in-kotlin
// Short url: https://stackoverflow.com/a/36753782/303685
interface ITree<out T> { }

class Tree<T>: ITree<T> { }

sealed class Node<T> : Tree<T>
{
  private readonly T _left;
  private readonly T _right;

  public Node(T left, T right)
  {
    _left = left;
    _right = right;
   }

   public T Left { get { return _left; } }
   public T Right { get { return _right; } }
 }

class Program
{
  static void CovarianceTest1()
  {
     ITree<object> tree = new Node<string>("Hello", "World!");
  }
}

我现在意识到,在做这个练习时,我学到了一些关于方差的新知识。

所以,我的第一个问题是:

构造函数中的输入位置是否允许使用共变型参数?在其他地方允许哪些类型参数忽略它们的方差限定符?

我学到的关于方差的另一件事是变体泛型类型参数甚至可能不会出现在变体接口声明中,如下例所示。

interface ITree<out T> { }

您会看到ITree<out T>接口在输入或输出位置没有T。这对我来说也是一种震惊。

我的第二个问题是:

我的另一个问题是,Kotlin中Nothing类型的C#等价物是什么?答案说Nothing是无法进一步推导出来的最多子类型。它与Any(或其他语言中最基本类型)完全相反。

要在C#中模拟该代码,这样做是没有意义的:

class Empty : Tree<null> { }

因为这只是非法的C#代码,而null似乎与Nothing不相似。

所以,我不得不假装一个假人来模仿Empty类声明。

sealed class Dummy { }

sealed class Empty : Tree<Dummy>
{
  private static Empty _empty = null;
  private static object syncLock = new object();
  private Empty() { }
  public Empty Instance
  {
    get
    {
    if (_empty == null)
    {
      lock (syncLock)
      {
        if (_empty == null)
        {
          _empty = new Empty();
         }
        }
       }

       return _empty;
      }
   }
}

我的第三个也是最后一个问题是:

因此,我的最后一个问题是,是否有一个地方包含Kotlin中所有可用类型及其描述的详尽列表?因为即使Basic Types page列出了大多数常见的列表,它似乎也不是一个详尽的列表。那里没有列出的类型都散布在the documentation上。就像上面的例子一样,它们只是在这里或那里出现在页面上。

1 个答案:

答案 0 :(得分:1)

Kotlin附带的所有类型都在其API reference中进行了描述,特别是{% extends 'base.html.twig' %} {% block top_header %}{% endblock %} //keep this empty , remove the top_header content 包:

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/