模式匹配和未分配的局部变量
pattern matching and unassigned local variable
我愿意:
(bool success, string name1, string name2) MyFunc() {
if (DateTime.Now.Year > 2020) return (false, "", ""); // error
return (true, "some value", "some value");
}
我的编码风格是先尝试处理错误,我尝试过:
void f() {
if (MyFunc() is (false, var name1, var name2)) return;
Console.WriteLine(name1);
}
我明白了
Error CS0165 Use of unassigned local variable 'name1'
在Console.WriteLine
这有效:
void f() {
if (!(MyFunc() is (true, var name1, var name2)))) return;
Console.WriteLine(name1);
}
我想了解为什么会这样?既然调用了MyFunc(),结果元组是可用的,为什么编译器不分配它让我使用它?
这本来是一种非常有用的返回状态+结果的方式,请求该功能是否有意义?
name1
和 name2
仅当 return 值 MyFunc()
与模式匹配时才会分配。并且,在那种情况下,方法 returns.
因此,Console.WriteLine(name1);
只有在 MyFunc()
不匹配模式时才会执行。并且,在这种情况下,name1
和 name2
将不会被分配。
这会起作用:
void f()
{
(var error, var name1, var name2) = MyFunc();
if (error) return;
Console.WriteLine(name1);
}
更新
这个问题的语法不太好读,所以我很困惑。仅在匹配成功后才根据需要执行解构。这 Sharplab.io example 表明这 :
void f() {
if (MyFunc() is (false, var name1, var name2)) {
Console.WriteLine(name1);
return;
}
}
在Release模式下转换成这样:
private void f()
{
ValueTuple<bool, string, string> valueTuple = MyFunc();
if (!valueTuple.Item1)
{
string item = valueTuple.Item2;
Console.WriteLine(item);
}
}
与其尝试检查失败,不如检查成功并使用变量:
void f() {
if (MyFunc() is (true, var name1, var name2)) {
Console.WriteLine(name1);
}
}
或者通过在块外使用变量来扩大范围:
var (success,name1,name2)= MyFunc();
if (!success) return;
Console.WriteLine(name1);
或者使用 switch 语句:
switch(MyFunc()) {
case (false, _,):
return ;
case (success, var name1,var name2):
Console.WriteLine(name1);
break;
}
您还可以定义单独的变量并利用赋值是表达式这一事实,但这变得很丑陋:
bool success;
string name1;
string name2;
if ( ((success,name1,name2)=MyFunc()) is (false,_,_)) {
return;
}
Console.WriteLine(name1);
你的 bool 变量没有被实例化,而字符串有。
试试这个:
static (bool success, string name1, string name2) MyFunc()
{
if (DateTime.Now.Year > 2020) return (false, "", "");
return (true, "some value", "some value");
}
static void f()
{
if (MyFunc() is var (b, name1,name2) && !b) return;
Console.WriteLine(name1);
}
public static void Main()
{
f();
}
我愿意:
(bool success, string name1, string name2) MyFunc() {
if (DateTime.Now.Year > 2020) return (false, "", ""); // error
return (true, "some value", "some value");
}
我的编码风格是先尝试处理错误,我尝试过:
void f() {
if (MyFunc() is (false, var name1, var name2)) return;
Console.WriteLine(name1);
}
我明白了
Error CS0165 Use of unassigned local variable 'name1'
在Console.WriteLine
这有效:
void f() {
if (!(MyFunc() is (true, var name1, var name2)))) return;
Console.WriteLine(name1);
}
我想了解为什么会这样?既然调用了MyFunc(),结果元组是可用的,为什么编译器不分配它让我使用它?
这本来是一种非常有用的返回状态+结果的方式,请求该功能是否有意义?
name1
和 name2
仅当 return 值 MyFunc()
与模式匹配时才会分配。并且,在那种情况下,方法 returns.
因此,Console.WriteLine(name1);
只有在 MyFunc()
不匹配模式时才会执行。并且,在这种情况下,name1
和 name2
将不会被分配。
这会起作用:
void f()
{
(var error, var name1, var name2) = MyFunc();
if (error) return;
Console.WriteLine(name1);
}
更新
这个问题的语法不太好读,所以我很困惑。仅在匹配成功后才根据需要执行解构。这 Sharplab.io example 表明这 :
void f() {
if (MyFunc() is (false, var name1, var name2)) {
Console.WriteLine(name1);
return;
}
}
在Release模式下转换成这样:
private void f()
{
ValueTuple<bool, string, string> valueTuple = MyFunc();
if (!valueTuple.Item1)
{
string item = valueTuple.Item2;
Console.WriteLine(item);
}
}
与其尝试检查失败,不如检查成功并使用变量:
void f() {
if (MyFunc() is (true, var name1, var name2)) {
Console.WriteLine(name1);
}
}
或者通过在块外使用变量来扩大范围:
var (success,name1,name2)= MyFunc();
if (!success) return;
Console.WriteLine(name1);
或者使用 switch 语句:
switch(MyFunc()) {
case (false, _,):
return ;
case (success, var name1,var name2):
Console.WriteLine(name1);
break;
}
您还可以定义单独的变量并利用赋值是表达式这一事实,但这变得很丑陋:
bool success;
string name1;
string name2;
if ( ((success,name1,name2)=MyFunc()) is (false,_,_)) {
return;
}
Console.WriteLine(name1);
你的 bool 变量没有被实例化,而字符串有。
试试这个:
static (bool success, string name1, string name2) MyFunc()
{
if (DateTime.Now.Year > 2020) return (false, "", "");
return (true, "some value", "some value");
}
static void f()
{
if (MyFunc() is var (b, name1,name2) && !b) return;
Console.WriteLine(name1);
}
public static void Main()
{
f();
}