C# 哪些单位类型可以为空?

C# 哪些单位类型可以为空?,c#,unity3d,nullable,C#,Unity3d,Nullable,为什么会这样 Renderer? myRenderer; 生成错误 The type 'Renderer' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable<T>' 不是吗 举个例子,我想能够写作 void ApplyMaterial(Material material) { Renderer? rend

为什么会这样

Renderer? myRenderer;
生成错误

The type 'Renderer' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable<T>'
不是吗

举个例子,我想能够写作

void ApplyMaterial(Material material)
{
    Renderer? renderer = targetDefinedExternally;
    renderer?.material = material;
}
相比之下,以下操作不会产生错误

Vector3? vector;
float? magnitude = vector3?.magnitude;
vector3?.Normalize();

这表明某些Unity类型是可空的,而其他类型则不是。我怎样才能分辨哪个是哪个?(有没有一种优雅的方法可以解决这个问题?

所有类型都可以为空。

类型可以是引用类型,也可以是值类型。引用类型本身可以为空。默认情况下,值类型不可为null,可以使用
前缀使其为null

是一个类,这意味着它是一个引用类型。因此,您不需要
,它可以工作:

void ApplyMaterial(Material material)
{
    Renderer renderer = targetDefinedExternally;
}
是一个结构,它是一个值类型。这就是为什么您可以这样做:

Vector3? myVector3;
如果您支持C#8,
渲染器?
也可以工作,因为它使用的是C#8的功能



也就是说,
renderer?.material=material在这两种情况下都不起作用,因为
?。
不能在赋值的LHS中使用:(

所有类型都可以为空。

类型可以是引用类型,也可以是值类型。引用类型本身可以为null。默认情况下,值类型不可以为null,可以使用
前缀使其为null

是一个类,这意味着它是一个引用类型。因此您不需要
,它可以工作:

void ApplyMaterial(Material material)
{
    Renderer renderer = targetDefinedExternally;
}
是一个结构,它是一种值类型。这就是为什么您可以执行以下操作:

Vector3? myVector3;
如果您支持C#8,
渲染器?
也可以工作,因为它使用的是C#8的功能



也就是说,
renderer?.material=material;
在这两种情况下都不起作用,因为
?。
不能在作业的LHS中使用:(

您不应该使用
renderer?.material=…
,因为null合并运算符在Unity中不可靠,因为Unity有自己的null对象实现,用于调试目的,导致无效(
null
)对象不是c#的
null
会导致异常。谢谢@Thomas。这回答了我对Sweeper答案的评论。您不应该使用
renderer?.material=…
,因为null合并操作符在Unity中不可靠,因为Unity有自己的null对象实现,用于调试目的,导致有效(
null
)对象不是c#的
null
导致异常。感谢@Thomas。这回答了我对Sweeper答案的评论。感谢您解释了结构与类在值类型与引用类型之间的关系。非常有用。我尝试了您建议的代码,但
渲染器?.material=material;
导致错误
左侧赋值的一侧必须是变量、属性或索引器,而
if(renderer!=null)renderer.material=material;
不是。@PaulMasri Stone实际上这不仅仅是因为Unity。你不能在赋值的左侧使用
?。
仅用于成员访问。Thomas关于在Unity中不使用它的观点仍然有效。感谢你解释了与值类型v相关的结构与类s引用类型。非常有用。我尝试了您建议的代码,但是
renderer?.material=material;
导致错误
赋值的左侧必须是变量、属性或索引器
if(renderer!=null)renderer.material=material;
不是。@PaulMasri Stone事实上这不仅仅是因为Unity。你不能在作业的左侧使用
?。
仅用于成员访问。Thomas关于不在Unity中使用它的观点仍然有效。