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;
}
}
}