C# 协变类型参数是否可以位于构造函数中的输入位置?

C# 协变类型参数是否可以位于构造函数中的输入位置?,c#,.net,kotlin,covariance,C#,.net,Kotlin,Covariance,在中,建议将泛型类型参数设置为共同变量,以允许创建空节点 由于树及其子类型的所有属性都是只读的(val),因此我得到泛型类型参数位于所有输出位置 但它确实在构造函数的输入位置具有类型参数 我认为该代码在C语言中无法工作,所以我尝试了一下,令我惊讶的是,它工作得很好 // See this: https://stackoverflow.com/questions/36753579/algebraic-data-types-in-kotlin // Short url: https://stacko

在中,建议将泛型类型参数设置为共同变量,以允许创建空节点

由于
树及其子类型的所有属性都是只读的(
val
),因此我得到泛型类型参数位于所有输出位置

但它确实在构造函数的输入位置具有类型参数

我认为该代码在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!");
  }
}
因为这只是非法的C代码,而且
null
似乎与
Nothing
不相似

因此,我不得不像这样伪造一个假人来模仿
空的
类声明

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;
      }
   }
}
密封类虚拟{}
密封类空:树
{
私有静态空_Empty=null;
私有静态对象syncLock=新对象();
私有空(){}
公共空实例
{
得到
{
如果(_empty==null)
{
锁定(同步锁定)
{
如果(_empty==null)
{
_empty=新的empty();
}
}
}
返回空;
}
}
}
我的第三个也是最后一个问题是:


因此,我的最后一个问题是,是否有一个地方包含Kotlin中所有可用类型的详尽列表及其描述?因为即使这些列表是最常见的,但它似乎并不是一个详尽的列表。没有列出的类型都被洒在上面。与上面的例子一样,它们只是出现在此处或那里的页面上,并在其中提及。

Kotlin附带的所有类型都在its中进行了描述,特别是
Kotlin
包:


你的问题太宽泛了,把许多不同的话题都混为一谈了。首先,关于构造函数,类不是变量,接口是变量。构造函数不是接口的一部分。你可以任意违反类本身的差异;这无关紧要,因为您唯一可以使用差异的地方就是通过接口处理类型。@PeterDuniho谢谢。你建议我把问题分解成多个问题吗?是的,我认为这样会更好。尽管如此,我预测你的#2问题的答案是“你做不到”(因为你做不到),而你的#3问题完全是离题的(它要求你推荐一些外部资源)。
class Empty : Tree<null> { }
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;
      }
   }
}