类型名称后面的符号“?”是什么意思?

4

我正在使用 Eto gui框架。我在他们的源代码中看到了一些神奇的语法,例如:

int x;
int? x;
void func(int param);
void func(int? param);

有什么不同?我感到困惑。 而符号?很难在谷歌上搜索。


可能是为什么私有变量定义上有一个问号?的重复问题。 - Shadow The Spring Wizard
可能是C# - 基本问题:'?'是什么?的重复。 - Soner Gönül
2个回答

9

这意味着它们是可空的, 它们可以保存 null 值.

如果你已经定义了:

int x;

那么你就不能做:

x = null; // this will be an error. 

但是如果您已经定义了x为:

int? x;

然后你可以这样做:

x = null; 

Nullable<T> 结构体

在 C# 和 Visual Basic 中,你可以在值类型后面使用 ? 符号将其标记为可空。例如,在 C# 中使用 int? 或者在 Visual Basic 中使用 Integer? 声明一个整数值类型,它可以被赋为 null。

个人认为可以使用 http://www.SymbolHound.com 来进行符号搜索,可以看一下 这里 的结果。

? 只是语法糖,等同于:

int? x 等同于 Nullable<int> x


5

struct(例如intlong等)默认情况下不能接受null。因此,.NET提供了一个通用的struct,名为Nullable<T>,其中T类型参数可以来自任何其他struct

public struct Nullable<T> where T : struct {}

它提供了一个名为 HasValue 的布尔属性,用于指示当前的 Nullable<T> 对象是否有值;还提供了一个名为 Value 的属性,用于获取当前 Nullable<T> 值的值(如果 HasValue == true,否则将抛出 InvalidOperationException):
public struct Nullable<T> where T : struct {
    public bool HasValue {
        get { /* true if has a value, otherwise false */ }
    }
    public T Value {
        get {
            if(!HasValue)
                throw new InvalidOperationException();
            return /* returns the value */
        }
    }
}

最后,回答你的问题,TypeName?Nullable<TypeName>的快捷方式。

int? --> Nullable<int>
long? --> Nullable<long>
bool? --> Nullable<bool>
// and so on

使用时:

int a = null; // exception. structs -value types- cannot be null
int? a = null; // no problem 

例如,我们有一个名为Table的类,在一个名为Write的方法中生成HTML <table>标签。看下面的代码:
public class Table {

    private readonly int? _width;

    public Table() {
        _width = null;
        // actually, we don't need to set _width to null
        // but to learning purposes we did.
    }

    public Table(int width) {
        _width = width;
    }

    public void Write(OurSampleHtmlWriter writer) {
        writer.Write("<table");
        // We have to check if our Nullable<T> variable has value, before using it:
        if(_width.HasValue)
            // if _width has value, we'll write it as a html attribute in table tag
            writer.WriteFormat(" style=\"width: {0}px;\">");
        else
            // otherwise, we just close the table tag
            writer.Write(">");
        writer.Write("</table>");
    }
}

以上类的用法-只是举个例子-像这样:

var output = new OurSampleHtmlWriter(); // this is NOT a real class, just an example

var table1 = new Table();
table1.Write(output);

var table2 = new Table(500);
table2.Write(output);

我们将会有:

// output1: <table></table>
// output2: <table style="width: 500px;"></table>

1
+1但是.. 值类型会被存储在栈中... - 不完全正确。请参阅:栈是实现细节的一部分,作者Eric Lippert - Habib

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接