三元运算符使用疑问:Color.FromArgb相关代码为何报错?
先来看你的代码片段:
private void Disable_Proxy_textboxes(bool v) { v = !v; address_textbox.Enabled = v; port_textbox.Enabled = v; port_label.ForeColor = Color.FromArgb(v?(255,255,255):(100, 100, 100)); address_label.ForeColor=v?(Color.FromArgb(255,255,255)):(Color.FromArgb(100,100,100)); }
你遇到的两个错误:
Predefined type 'System.ValueTuple`3' is not defined or imported cannot convert from '(int, int, int)' to 'int'
错误背后的原理
你提到文档里说“第一个表达式和第二个表达式的类型必须相同,或者两者之间存在隐式转换”——这个规则你没理解错,但问题出在你对Color.FromArgb参数传递的误解,以及C#里(x,y,z)语法的含义:
(255,255,255)是值元组,不是三个独立参数
在C#中,用逗号分隔的括号语法(a,b,c)创建的是一个**ValueTuple<int,int,int>对象**,而不是三个单独的int参数。Color.FromArgb并没有提供接受ValueTuple<int,int,int>作为输入的重载方法——它的重载要么是:- 单个
int参数(代表合并的ARGB值) - 三个单独的
int参数(R、G、B分量) - 四个单独的
int参数(A、R、G、B分量)
- 单个
编译器的匹配逻辑导致类型不匹配
当你写Color.FromArgb(v?(255,255,255):(100, 100, 100))时,编译器首先会计算三元表达式的结果类型:ValueTuple<int,int,int>。然后它会去查找Color.FromArgb的重载,发现没有能直接接收这个元组的重载,于是尝试匹配最接近的——也就是单int参数的重载。这时候就会出现第二个错误:无法把元组转换成int。至于第一个错误,如果你的项目目标框架版本低于.NET Framework 4.7、.NET Core 1.0或者.NET Standard 2.0,ValueTuple类型是默认不包含在框架里的,所以编译器会提示找不到这个类型。
对比你写的正确代码
你正确的那行address_label.ForeColor=v?(Color.FromArgb(255,255,255)):(Color.FromArgb(100,100,100));是完全符合规则的:三元运算符的两边都是Color类型(Color.FromArgb的返回值),类型一致,所以编译器可以正常处理,直接把结果赋值给ForeColor(它的类型就是Color)。
简单总结:你试图用三元运算符返回一个元组,然后把这个元组当作参数传给Color.FromArgb,但这个方法根本不接受元组作为输入——这才是错误的核心,和三元运算符本身的规则无关,而是参数传递的类型不匹配。
内容的提问来源于stack exchange,提问作者Rishav

