如何将int转换为可空类型?

时间:2014-07-16 10:07:23

标签: c#

我只是做简单的int swap程序。我也刚刚学会了铸造,所以我在这个程序中尝试了。但我收到一个错误,说我应该做一个明确的演员。

我认为我不了解演员的概念。有什么问题?

static void Main(string[] args)
{
    Console.WriteLine("Enter the FIRST Integer.");
    string tempint1 = Console.ReadLine();
    int int1 = Convert.ToInt32(tempint1);

    Console.WriteLine("Enter the SECOND Integer.");
    string tempint2 = Console.ReadLine();
    int int2 = Convert.ToInt32(tempint2);

    Console.WriteLine();

    int? swapInt = null;
    swapInt = (int)int1;
    int1 = int2;
    int2 = swapInt;

    Console.WriteLine("The integers have been swapped!");
    Console.WriteLine("The FIRST INTEGER is now " + int1);
    Console.WriteLine("The SECOND INTEGER is now " + int2);
    Console.WriteLine();
}

5 个答案:

答案 0 :(得分:6)

int?是名为Nullable<int>的类型的简写。显然,intNullable<int>不是同一类型。 Nullable<int>有一个名为Value的属性,该属性是实际的int。要访问Value属性,首先应检查HasValue属性是否为true(就像检查引用类型是否为null一样)。

现在是问题所在:

intNullable<int>的隐式转换(请记住,这与int?相同)并且该转换表示创建了新的Nullable<int>,{ {1}}设置为HasValue,其true设置为初始Value的值。因此,您可以这样做:

int

另一方面,从int a = 5 int? b = 5; // implicit conversion int? c = a; // implicit conversion int? d = c; Nullable<int>的相反转换不会隐式存在,因为int可能将其Nullable<int>属性设置为{{ 1}},这意味着常规HasValue将无法描述它,并且编译器不知道在这种情况下你想要发生什么。所以,这就是你无法做到的原因:

false

相反,你想要做这样的事情:

int

强制转换与问题无关(这只是编译器的建议,但实际上并不是你想要做的)。为了学习:强制转换只是指令编译器将一种类型的表达式视为另一种(希望是兼容的)类型的表达式,可能是通过在这两种类型之间应用转换(如果在任何地方定义了这种转换) )。

答案 1 :(得分:5)

swapInt是一个可以为空的int及以下:

你试图将一个可以为空的int赋给一个解决问题的int:

int2 = swapInt;

如果将其更改为以下版本,则可以,

int2 = swapInt.Value;

此外,这段代码:

int? swapInt = null;
swapInt = (int)int1;
int1 = int2;
int2 = swapInt;

可以改为以下一个:

 int? swapInt = int1;
 int1 = int2;
 int2 = swapInt.Value;

您不必将已经整数转换为int (int)int1;

<强>更新

我必须对您的计划发表一些意见,您可以将其纳入计划。

static void Main(string[] args)
{
    // Get the users input.

    Console.WriteLine("Enter the FIRST Integer.");
    string a = Console.ReadLine();

    Console.WriteLine("Enter the SECOND Integer.");
    string b = Console.ReadLine();

    // Variables, in which we will store the parsed strings that user passes.
    int integerA;
    int integerB;

    // Try to parse the strings that user passes to create two integer numbers.
    // If either parse of a or parse of b fail, then the method Int32.TryParse()
    // will return false and the code in the body of if, will not be executed.
    if(Int32.TryParse(a, out integerA) && Int32.TryParse(b, out integerB))
    {
        // Pass the integers to the methods called swap
        Swap(ref integerA, ref integerB);
        Console.WriteLine("The integers have been swapped!");
        Console.WriteLine("The FIRST INTEGER is now " + int1);
        Console.WriteLine("The SECOND INTEGER is now " + int2);
    }

    Console.WriteLine();
}

// This methods makes the actual swap
static void Swap(ref int a, ref int b)
{
    int temp = a;
    a = b;
    b = temp;
}

如果你仔细阅读上面的代码,那么你会注意到我们没有使用nullables,实际上,在这种情况下我们不需要它们。

有关您的信息,C#中有一个泛型方法,可用于交换对象,无论它们是否为数字。此方法的名称为Swap,其签名如下:

static void Swap<T>(ref T lhs, ref T rhs)

您可以使用以下方法:

Swap<int>(ref integerA, ref integerB);

有关此方法的详细信息,请查看here

  

ref代表什么?

MSDN中所述:

  

ref关键字导致参数通过引用传递,而不是通过值传递。通过引用传递的效果是方法中对参数的任何更改都会反映在调用方法中的基础参数变量中。引用参数的值始终与基础参数变量的值相同。

示例让我们有一个名为Increment的方法:

public void Increment(int x)
{
    // This will increase the value of variable x by one.
    // This change is only visible insied the body of this method
    // and it is not reflected outside of it.
    x++;
}

如果我们定义了如下方法:

public void Increment(ref int x)
{
    x++;
}

x的值的变化也会在名为Increment的方法体外显现。

  

为什么会这样?

因为在第一种情况下,我们传递了x中存储的值的副本,而在第二种情况下,我们没有传递副本< / strong>这个值。因此,第二种情况的任何变化也将反映在名为Incerement的方法体外。

答案 2 :(得分:1)

问题是从int?int存在无隐式转化。由于int?可以为null,编译器不允许这样做,它希望您明确地执行转换:

int2 = (int) swapInt;

通过这样做,你告诉编译器&#34; 我知道我在做什么。&#34;,如果swapInt为空,这将抛出异常在运行时。

答案 3 :(得分:-1)

你的问题就在这一行

int2 = swapInt;

int2integerswapIntnullable intnull?。您不能这样分配,因为编译器无法直接将null?转换为null。因此错误

  

无法隐式转换类型&#39; int?&#39; to&#39; int&#39;。存在显式转换(您是否错过了演员?)

当它无法执行此操作时,它会要求您转换它。

所以改变

int2 = swapInt;

if (swapInt.HasValue)
    int2 = swapInt.Value;

可空类型
int这样的值类型不能为空。可空类型是存储值类型的类型,可以为null。

要从中提取价值,请先检查它们是否有价值。这样做是检查HasValue。它返回一个布尔值,如果为真,我们使用swapInt.Value提取值。

您可以像(int)swapInt一样进行投射,但如果它没有任何值,它将抛出异常。

您可以投出或获取其价值。两者的性能与cast相同,是Value属性的语法糖。

答案 4 :(得分:-1)

swapInt是可以为空的类型,方法GetValueOrDefault如果不为null则返回值,否则返回基础类型的默认值

int2 = swapInt.GetValueOrDefault()