关于ToString()、ToKnowColor()及属性返回值为类类型的理解
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Drawing; 6 using System.Windows.Forms; 7 8 namespace ColorScroll 9 { 10 class ColorScroll:Form 11 { 12 Panel panel; 13 Label[] alabelName = new Label[3]; 14 Label[] alabelValue = new Label[3]; 15 VScrollBar[] avscroll = new VScrollBar[3]; 16 17 static void Main(string[] args) 18 { 19 Application.Run(new ColorScroll()); 20 } 21 public ColorScroll() 22 { 23 Text = "Color Scroll"; 24 Color[] acolor = { Color.Red,Color.Green,Color.Blue}; 25 //以下为测试使用 26 Console.WriteLine(acolor[0]); 27 Console.WriteLine(acolor[1].ToString()); 28 Console.WriteLine(acolor[2].ToKnownColor()); 29 Console.WriteLine(Color.Red.ToKnownColor()); 30 Console.WriteLine((Color.Red).GetType()); 31 32 //Create the panel 33 panel = new Panel(); 34 panel.Parent = this; 35 panel.Location = new Point(0,0); 36 panel.BackColor = Color.White; 37 38 //Loop though the three colors 39 for (int i = 0; i < 3; i++) 40 { 41 alabelName[i] = new Label(); 42 alabelName[i].Parent = panel; 43 alabelName[i].ForeColor = acolor[i]; 44 alabelName[i].Text = "&" + acolor[i].ToKnownColor(); 45 alabelName[i].TextAlign = ContentAlignment.MiddleCenter; 46 47 avscroll[i] = new VScrollBar(); 48 avscroll[i].Parent = panel; 49 avscroll[i].SmallChange = 1; 50 avscroll[i].LargeChange = 16; 51 avscroll[i].Minimum = 0; 52 avscroll[i].Maximum = 255 + avscroll[i].LargeChange - 1; 53 avscroll[i].ValueChanged += new EventHandler(ColorScroll_ValueChanged); 54 avscroll[i].TabStop = true; 55 56 alabelValue[i] = new Label(); 57 alabelValue[i].Parent = panel; 58 alabelValue[i].TextAlign = ContentAlignment.MiddleCenter; 59 } 60 Color color = BackColor; 61 62 //Generates ValueChanged Event 63 avscroll[0].Value = color.R; 64 65 avscroll[1].Value = color.G; 66 avscroll[2].Value = color.B; 67 68 OnResize(EventArgs.Empty); 69 } 70 71 protected override void OnResize(EventArgs e) 72 { 73 base.OnResize(e); 74 75 int cx = ClientSize.Width; 76 int cy = ClientSize.Height; 77 int cyFont = Font.Height; 78 79 panel.Size = new Size(cx/2,cy); 80 81 for (int i = 0; i < 3; i++) 82 { 83 //文字标签的位置和尺寸大小 84 alabelName[i].Location = new Point(i * cx/6,cyFont/2); 85 alabelName[i].Size = new Size(cx/6,cyFont); 86 87 //滚动条的位置和尺寸大小 88 avscroll[i].Location = new Point((4 * i + 1) * cx / 24, 2 * cyFont); 89 //avscroll[i].Location = new Point(i * cx / 6, 2*cyFont); 90 avscroll[i].Size = new Size(cx/12,cy - 4 * cyFont); 91 92 //数字标签的位置和尺寸大小 93 alabelValue[i].Location = new Point(i * cx/6,cy-3*cyFont/2); 94 alabelValue[i].Size = new Size(cx/6,cyFont); 95 } 96 } 97 98 void ColorScroll_ValueChanged(object sender, EventArgs e) 99 { 100 for (int i = 0; i < 3; i++) 101 { 102 if ((VScrollBar)sender == avscroll[i]) 103 { 104 alabelValue[i].Text = avscroll[i].Value.ToString(); 105 } 106 } 107 BackColor = Color.FromArgb(avscroll[0].Value, 108 avscroll[1].Value, 109 avscroll[2].Value); 110 } 111 } 112 }
上述代码中alabelName[i].Text = "&" + acolor[i].ToKnownColor();是用于在标签页中展示文字,类型是string,按照惯常思维应该使用alabelName[i].Text = "&" + acolor[i].ToString();就可以了,但是实际不是这样;
在上述代码的第27行中加入测试代码Console.WriteLine(acolor[1].ToString());
运行后如下:
显示的是Color [Green],而不是我们期待的Green;
这是为什么呢?由于我们打开定义看看,如下:
我们发现Color.Red或Color.Green均是静态属性,且返回值为Color类类型,因此Color.Red或Color.Green均为Color类类型,而不是string类型,所以在使用tostring()时输出来的就是Color [Red]或Color [Green]。
使用测试代码Console.WriteLine((Color.Red).GetType());再看一下,如下
Color.Red在GetType()中的返回类型是System.Drawing.Color,也就是Color类类型。
我们再进一步,使用.Net Reflector看一下,如下:
public static Color Red { get; }属性的返回值,返回的是new Color类实例;所以在使用GetType()后,输出的是Color类类型;
以上就是第一个疑问:为什么使用ToString()输出的是类类型,而不是具体的颜色文字;
第二个疑问是:为什么使用ToKnonwColor()可以输出具体的颜色文字呢?
我们先看一下ToKnowColor()的定义,如下:
ToKnowColor()返回的是KnowColor的值(注意:KnowColor是枚举类型);
通过.Net Reflector可以看到,ToKnowColor()返回了KnowColor.Red枚举值。
Console.WriteLine(acolor[2].ToKnownColor());
Console.WriteLine(Color.Red.ToKnownColor());
以上两行测试码,输出的是Blue和Red,如下所示
第三个疑问:Color.Red.ToKnownColor()中Color.Red是属性,为什么还可以在.后面调用ToKnowColor()函数呢?
这其实在第一个疑问中已经可以得到答案了,Color.Red实质上返回的是 return new Color(KnowColur.Red);类实例,Colour的类实例是可以调用ToKnowColor()函数的;
通过测试代码:Console.WriteLine(Color.Red.ToKnownColor());可以正常输出如下: