空泛型类型c#
这不起作用,因为C#中的所有类型都不能为null。让我惊讶的是,当我在Java中尝试类似的东西时,它是有效的!我已经看到了一些关于堆栈溢出的相关问题,但它们没有给出我想要的结果。我不想使用空泛型类型c#,c#,generics,null,C#,Generics,Null,这不起作用,因为C#中的所有类型都不能为null。让我惊讶的是,当我在Java中尝试类似的东西时,它是有效的!我已经看到了一些关于堆栈溢出的相关问题,但它们没有给出我想要的结果。我不想使用默认值(E) 您需要一个泛型类型约束,说明E必须是引用类型: Node<E> n = new Node<E>(null, null, null); int?不是int,但也不是int,是吗 让我惊讶的是,当我在Java中尝试类似的东西时,它是有效的 这是因为Java泛型类型是通过类型擦
默认值(E)
您需要一个泛型类型约束,说明E
必须是引用类型:
Node<E> n = new Node<E>(null, null, null);
int?
不是int
,但也不是int
,是吗
让我惊讶的是,当我在Java中尝试类似的东西时,它是有效的
这是因为Java泛型类型是通过类型擦除实现的,这实际上意味着它们都是Java.lang.Object
的后代
例如,您不能在Java中使用primitiveint
作为节点的类型参数:您必须使用Java.lang.Integer
。因此,无论T
如何,都可以为element
分配null
在C#中,对类型参数没有这样的限制:编写节点
是完全合法的。但是,使用类型为int
的element
,您无法再写入element=null
,这是您看到的错误的根本原因
除了您提到的default(T)
方法之外,您还可以要求T
是一个引用类型,如下所示:
var y = new Node<int?>(null, null, null);
公共类节点:i位置,其中E:class{
...
}
现在将null
传递给节点的构造函数的初始参数是合法的,但是使用任何值类型实例化节点
是非法的,包括null
如果我们这样做:
var y = new Node<int?>(null, null, null);
首先,创建一个简单的界面
public class Node<E> : IPosition<E> where E : class {
...
}
这样写
if (this.element != null) { .. }
public static IOptional<TOutput> Match<TInput, TOutput>(
this IEnumerable<TInput> maybe,
Func<TInput, TOutput> some, Func<TOutput> nothing)
{
if (maybe.Any())
{
return new Maybe<TOutput>(
some(
maybe.First()
)
);
}
else
{
return new Maybe<TOutput>(
nothing()
);
}
}
像这样
if (this.element != null) { .. }
this.element.Select(e => { doSomething(e); return true; })
public static IOptional<TOutput> Match<TInput, TOutput>(
this IEnumerable<TInput> maybe,
Func<TInput, TOutput> some, Func<TOutput> nothing)
{
if (maybe.Any())
{
return new Maybe<TOutput>(
some(
maybe.First()
)
);
}
else
{
return new Maybe<TOutput>(
nothing()
);
}
}
或者编写一个小的扩展方法
if (this.element.Any())
{
var elem = this.element.First();
// do something
}
Node n=新节点(null,null,null)
您必须提供特定的类型才能工作。我不需要默认的(E)
但是您不需要吗?这怎么不正是你想要的呢?@Forecast Well你接受了一个禁止你使用非空类型的答案。如果希望能够使用不可为空的类型,则不应该这样做。如果您确实希望能够使用不可为null的类型,则需要描述您希望发生的事情。它们不能有null
值(根据定义,因为它们是不可为null的类型)。您希望它们具有什么价值?@Forecast您可以自己查看源代码以获得列表。它从不尝试在任何类型的T
中存储任何null
值,它只存储该类型的值,这也是您应该做的。@Forecast您的类型现在不再是泛型的,您已经丢失了所有静态类型检查。看我的答案,我还建议删除代码中的所有null,尤其是作为构造函数或方法中的参数
this.element.Select(e => { doSomething(e); return true; })
if (this.element.Any())
{
var elem = this.element.First();
// do something
}
public static IOptional<TOutput> Match<TInput, TOutput>(
this IEnumerable<TInput> maybe,
Func<TInput, TOutput> some, Func<TOutput> nothing)
{
if (maybe.Any())
{
return new Maybe<TOutput>(
some(
maybe.First()
)
);
}
else
{
return new Maybe<TOutput>(
nothing()
);
}
}
var result = this.element
.Match(
some: e => e.ToString(),
nothing: () => "Ups"
)
.First();