如何将整型转换为可空类型
本文关键字:类型 转换 整型 | 更新日期: 2023-09-27 18:13:19
我只是在做一个简单的int交换程序。我也刚刚学会了选角,所以我在这个节目中尝试了一下。但我得到一个错误,说我应该做显式强制转换。
我想我不理解强制类型转换的概念。有什么问题吗?
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();
}
swapInt
是一个可空的整型浮点数,且小于:
你试图将一个可空的整型赋值给一个整型这就是问题所在:
int2 = swapInt;
如果您将其更改为以下内容,则可以,
int2 = swapInt.Value;
此外,这段代码:
int? swapInt = null;
swapInt = (int)int1;
int1 = int2;
int2 = swapInt;
可以改成如下:
int? swapInt = int1;
int1 = int2;
int2 = swapInt.Value;
你不需要将一个已经是整型的转换为整型,(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;
}
如果你仔细阅读上面的代码,那么你会注意到我们没有使用空值,实际上,在这种情况下我们不需要它们。
对于你的信息,在c#中有一个泛型方法,它可以用于交换对象,无论它们是数字还是非数字。这个方法的名称是Swap
,它的签名如下:
static void Swap<T>(ref T lhs, ref T rhs)
你可以这样使用这个方法:
Swap<int>(ref integerA, ref integerB);
有关此方法的更多信息,请查看此处。
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
中的值的副本,而在第二种情况下,我们没有传递该值的副本。因此,第二种情况下的任何更改也将反映在称为Incerement
的方法体之外。
int?
是称为Nullable<int>
的类型的简写。显然,int
和Nullable<int>
不是同一类型。Nullable<int>
有一个属性叫做Value
,这个属性就是实际的int
。要访问Value
属性,首先应该检查HasValue
属性是否为true
(就像检查引用类型是否为null
一样)。
现在问题来了:
有一个从int
到Nullable<int>
的隐式转换(记住,这与int?
相同),该转换表示创建一个新的Nullable<int>
,其中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>
可能将其HasValue
属性设置为false
,这意味着常规的int
将无法描述它,编译器不知道在这种情况下您想要发生什么。所以,这就是为什么你不能这样做:
int? a = 5;
int b = a; // illegal, no implicit conversion exists
相反,您应该这样做:
int? a = 5;
if(a.HasValue)
{
int b = a.Value;
// ...
}
else
{
// ...
}
强制类型转换与问题无关(这只是编译器的建议,但实际上并不是您在这里想要做的)。为了便于学习:强制转换只是给编译器的一条指令,将一种类型的表达式视为另一种(希望兼容)类型的表达式,可能通过在这两种类型之间应用转换(如果在任何地方定义了这种转换)。
问题是没有从int?
到int
的隐式转换。由于int?
可以为空,编译器不允许这样做,它希望您显式地执行强制转换:
int2 = (int) swapInt;
这样做,你告诉编译器"我知道我在做什么。",如果swapInt
为空,将在运行时抛出异常。
swapInt
是一个可空类型,如果方法GetValueOrDefault
不为空则返回值,否则返回底层类型
int2 = swapInt.GetValueOrDefault()
你的问题在这一行
int2 = swapInt;
int2
为integer
, swapInt
为nullable int
或null?
。你不能这样赋值,因为编译器不能直接将null?
转换为null
。因此出现错误
不能隐式转换int类型?'到'int'。存在显式转换(您是否缺少强制类型转换?)
当它不能这样做时,它要求您转换它。
So Change
int2 = swapInt;
if (swapInt.HasValue)
int2 = swapInt.Value;
<<p> 可空类型/strong>像
int
这样的值类型不能为空。可空类型是存储值类型并且可以为空的类型。
要从中提取值,首先检查它们是否有值。这是通过检查HasValue
完成的。它返回一个布尔值,如果为真,我们使用swapInt.Value
提取值。
你可以像(int)swapInt
一样强制转换,但是如果它没有任何值,它会抛出异常。
可以强制转换或获取其值。两者的性能相同,因为cast是Value属性的语法糖。