空泛型类型c#

空泛型类型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泛型类型是通过类型擦

这不起作用,因为C#中的所有类型都不能为null。让我惊讶的是,当我在Java中尝试类似的东西时,它是有效的!我已经看到了一些关于堆栈溢出的相关问题,但它们没有给出我想要的结果。我不想使用
默认值(E)

您需要一个泛型类型约束,说明
E
必须是引用类型:

Node<E> n = new Node<E>(null, null, null);
int?
不是
int
,但也不是
int
,是吗

让我惊讶的是,当我在Java中尝试类似的东西时,它是有效的

这是因为Java泛型类型是通过类型擦除实现的,这实际上意味着它们都是
Java.lang.Object
的后代

例如,您不能在Java中使用primitive
int
作为
节点的类型参数:您必须使用
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();