CS1503 无法转换 MyType?到我的类型
CS1503 Cannot convert MyType? to MyType
我似乎无法理解可空性在 C# 8 中的工作原理。在下面的 IF 表达式中,很明显 myType
是 not null。我仍然收到编译器错误,说它可能是 MyType OR null
而不是 MyType
.
public Method(MyType mytpe)
{
System.Console.WriteLine("Meh");
}
public class AwesomeType
{
public MyType? MyType { get; set; }
}
//...
var awesome = new AwesomeType();
var myType = awesome.MyType;
if (myType != null)
{
Method(myType); // CS1503 Cannot convert MyType? to MyType
}
以下工作正常
var awesome = new AwesomeType();
var myType = awesome.MyType;
if (myType != null)
{
Method(myType.Value);
}
我认为第一种方法应该可行,因为编译器可以在 if 条件的 true 块内推断出不可为空性。为什么编译器仍然报错?
Why does the compiler still complain?
这与可空对象在 C# 中的工作方式有关。表示对象可以为空的 ?
运算符基本上告诉编译器“嗨,编译器 - 这个对象可能为空,没关系。”
这对你有什么用,例如 bool?
是允许你表示一个通常不想要的状态。
通常 bool
只能是 true
和 false
,如果它从未被初始化,它 可能 是 null
.如果 bool
从未初始化访问它的值将抛出 NullReferenceException
.
同时 bool?
(表示可为空的布尔值)告诉编译器'如果布尔值为空,则将 null
视为它的值,而不是抛出异常并抱怨它没有值。'(在简化意义上)
使用可空类型的诀窍在于,它们不会像不可空类型那样被隐式处理。它们基本上是完全不同的对象,除非你这么说。
当你想到它时,它很有意义。如果你可以设置一个普通的布尔值,比如 bool isLightOn = true;
并将其设置为 isLightOn = null;
,那将是非常奇怪的,这甚至意味着什么?灯会熄灭吗,不,那是错误的..,它会闪烁灯吗?当您将变量设置为变量通常不使用的值(如 null
)时,编译器不知道您打算发生什么。这是好事!它会导致各种奇怪的问题。
这导致了您遇到的问题。
bool? isLightOn = false;
// compiler checks to see if a bool? can have a null state
// it determines that bool? can be true, false, or null
// it says this line is okay
if(isLightOn != null)
{
// compiler says the variable isn't null,
// but it still CAN be null, for example, if something within this code block changes it's value,
// or if that variable is accessed by another thread
// becuase of this the compiler will not consider this light
// as either true, false(a normal bool) it says 'there's still
// a possibility that by the time it's used it may not be
// either true, or false, therefor it should be considered as
// being maybe null in my eyes(the compiler).'
// compiler checks to see if the object you're passing as a parameter is a valid object
// compiler sees that your object can be true, false, or null
// compiler says 'if i give this method this object without asking the programmer if it's okay, it may break the program becuase the method doesn't know how to deal with null values'
TestLight(isLightOn);
// compiler checks to see if the object you're passing as a parameter is a valid object
// compiler sees that the programmer explicitly told it to ignore the null value and treat is as if it were false, and allows you to pass that variable as parameter
TestLight((bool)isLightOn);
}
void TestLight(bool lightOn)
{
}
当您检查可空对象是否为空时,这只是检查它的值。由于这是对象所处的有效状态,因此编译器会照常进行并且不会抱怨。
当您尝试将该值实际用于使用不可为 null 的对象作为参数的对象时,我们 运行 进入这个问题,如果null
对象状态不是该对象的有效状态?
因此它将对象的可空版本和不可空版本视为完全不同的类型,但在两者之间进行显式转换。
其原因可以归结为您试图以一种会丢失信息或有损操作的方式使用变量,如果您愿意的话。
编译器不会假定您要忽略可空对象的有效值。
它迫使你说'嘿编译器,将这个可为空的对象视为不可为空的对象,如果它的值不是预期的,请将其更改为预期值(默认值)。对于 bool?
,如果有效值为 null
并且您说 'treat it like a non-nullable bool'(通过使用显式转换 (bool)bool?
,编译器会说“好的!null
基本上是 default
所以当你将它作为参数传递时,这就是它的新值'。
我似乎无法理解可空性在 C# 8 中的工作原理。在下面的 IF 表达式中,很明显 myType
是 not null。我仍然收到编译器错误,说它可能是 MyType OR null
而不是 MyType
.
public Method(MyType mytpe)
{
System.Console.WriteLine("Meh");
}
public class AwesomeType
{
public MyType? MyType { get; set; }
}
//...
var awesome = new AwesomeType();
var myType = awesome.MyType;
if (myType != null)
{
Method(myType); // CS1503 Cannot convert MyType? to MyType
}
以下工作正常
var awesome = new AwesomeType();
var myType = awesome.MyType;
if (myType != null)
{
Method(myType.Value);
}
我认为第一种方法应该可行,因为编译器可以在 if 条件的 true 块内推断出不可为空性。为什么编译器仍然报错?
Why does the compiler still complain?
这与可空对象在 C# 中的工作方式有关。表示对象可以为空的 ?
运算符基本上告诉编译器“嗨,编译器 - 这个对象可能为空,没关系。”
这对你有什么用,例如 bool?
是允许你表示一个通常不想要的状态。
通常 bool
只能是 true
和 false
,如果它从未被初始化,它 可能 是 null
.如果 bool
从未初始化访问它的值将抛出 NullReferenceException
.
同时 bool?
(表示可为空的布尔值)告诉编译器'如果布尔值为空,则将 null
视为它的值,而不是抛出异常并抱怨它没有值。'(在简化意义上)
使用可空类型的诀窍在于,它们不会像不可空类型那样被隐式处理。它们基本上是完全不同的对象,除非你这么说。
当你想到它时,它很有意义。如果你可以设置一个普通的布尔值,比如 bool isLightOn = true;
并将其设置为 isLightOn = null;
,那将是非常奇怪的,这甚至意味着什么?灯会熄灭吗,不,那是错误的..,它会闪烁灯吗?当您将变量设置为变量通常不使用的值(如 null
)时,编译器不知道您打算发生什么。这是好事!它会导致各种奇怪的问题。
这导致了您遇到的问题。
bool? isLightOn = false;
// compiler checks to see if a bool? can have a null state
// it determines that bool? can be true, false, or null
// it says this line is okay
if(isLightOn != null)
{
// compiler says the variable isn't null,
// but it still CAN be null, for example, if something within this code block changes it's value,
// or if that variable is accessed by another thread
// becuase of this the compiler will not consider this light
// as either true, false(a normal bool) it says 'there's still
// a possibility that by the time it's used it may not be
// either true, or false, therefor it should be considered as
// being maybe null in my eyes(the compiler).'
// compiler checks to see if the object you're passing as a parameter is a valid object
// compiler sees that your object can be true, false, or null
// compiler says 'if i give this method this object without asking the programmer if it's okay, it may break the program becuase the method doesn't know how to deal with null values'
TestLight(isLightOn);
// compiler checks to see if the object you're passing as a parameter is a valid object
// compiler sees that the programmer explicitly told it to ignore the null value and treat is as if it were false, and allows you to pass that variable as parameter
TestLight((bool)isLightOn);
}
void TestLight(bool lightOn)
{
}
当您检查可空对象是否为空时,这只是检查它的值。由于这是对象所处的有效状态,因此编译器会照常进行并且不会抱怨。
当您尝试将该值实际用于使用不可为 null 的对象作为参数的对象时,我们 运行 进入这个问题,如果null
对象状态不是该对象的有效状态?
因此它将对象的可空版本和不可空版本视为完全不同的类型,但在两者之间进行显式转换。
其原因可以归结为您试图以一种会丢失信息或有损操作的方式使用变量,如果您愿意的话。
编译器不会假定您要忽略可空对象的有效值。
它迫使你说'嘿编译器,将这个可为空的对象视为不可为空的对象,如果它的值不是预期的,请将其更改为预期值(默认值)。对于 bool?
,如果有效值为 null
并且您说 'treat it like a non-nullable bool'(通过使用显式转换 (bool)bool?
,编译器会说“好的!null
基本上是 default
所以当你将它作为参数传递时,这就是它的新值'。