在Winforms中生成冗余

时间:2015-12-10 11:15:52

标签: c# .net winforms

在查看Winforms中生成的代码时,我注意到一些看似毫无意义的内容:

this.aButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), 
                                                       ((int)(((byte)(101)))), 
                                                       ((int)(((byte)(162))))); 

Color.FromArgb可以使用int,那么为什么需要那些(int)和(byte)转换?为什么VS不会生成

this.aButton.BackColor = System.Drawing.Color.FromArgb(0, 101, 162)?

2 个答案:

答案 0 :(得分:2)

嗯,它看起来像一些“万无一失”的机制。由于每个颜色分量值应小于256(颜色限制为8位),因此如果开发人员以某种方式输入大于255的值作为颜色分量,则将此值转换为byte将阻止编译程序。

即。这样:(byte)256将生成编译器错误,从而向开发人员显示颜色组件值的问题。

答案 1 :(得分:0)

这是设计师如何序列化属性值的人工制品。该属性使用TypeConverter序列化为InstanceDescriptor

实例描述符包含从颜色对象的R,G和B属性存储为字节的参数,如下所示:

var color = System.Drawing.Color.FromArgb(255, 128, 64);
var converter = TypeDescriptor.GetConverter(color);

var result = (InstanceDescriptor) converter.ConvertTo(color, typeof(InstanceDescriptor));
var arguments = result.Arguments.Cast<object>().ToList();

Console.WriteLine(arguments[0] is byte);

之后,实例描述符转换为CodeDom,然后保存为C#代码。

CodeDom只是准确地再现了它的内容,因为C#没有本地字节类型,它将一个强制转换输出到一个字节。然后CodeDom看到它调用一个需要int的方法,但它有一个byte,所以将这些值转换为int,这是因为存在一个字节的重载或稍后加入。

CodeDom以这种方式表现,因为它不会造成任何伤害并且很容易。负责序列化常量值的部分不需要知道或关心如何使用该值。负责生成方法调用的部分不需要知道或关心值的来源(在这种情况下是一个常量,但它可能是变量,属性,方法调用等)。冗余将是由编译器拾取并优化掉。

ColorConverter可以通过在为实例描述符生成参数时首先将字节转换为int来避免这种情况,但同样,额外工作和复杂性的重点是什么。