1

当我们分配这样的值时,性能是否会下降?

Dropdown1.Enable = dropdown2.Enable = dropdown3.Enable = false;

提前致谢。

4

3 回答 3

4

答案是没有影响——它相当于三个赋值语句。

甚至没有get调用任何操作,如下所示:

控制台应用项目:

using System;
using System.Diagnostics;

namespace ConsoleApplication5
{
    public class X

    {
        private int _a;
        private int _b;

        public int A
        {
            get
            {
                Console.WriteLine("get A");
                return _a + 1;
            }
            set
            {
                Console.WriteLine("set A");
                _a = value;
            }
        }

        public int B
        {
            get
            {
                Console.WriteLine("get B");
                return _b + 2;
            }
            set
            {
                Console.WriteLine("set B");
                _b = value;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var x = new X();

            Console.WriteLine("Assign");
            int y = x.B = x.A = 125;

            Console.WriteLine("Read");
            Console.WriteLine("y " + y + " x.B " + x.B + " x.A " + x.A);

            Console.ReadLine();
        }
    }
}

生成:

Assign
set A
set B
Read
get B
get A
y 125 x.B 127 x.A 126

请注意,在分配阶段,不会调用“get”,即使 A 和 B 的 getter 返回的值与设置在它们上的值不同,最终分配给y的值是表达式的 RHS 上的源值。

于 2012-10-11T11:22:23.413 回答
1

我可能从其他两个答案中误解了一些东西,但我认为没有getters人被解雇。在所有三种情况下,为属性触发的是setter 。此外,我很确定 IL 只是将false值推入堆栈三次,并为每次触发一次设置器。

对于以下课程:

public class Test
{
    public bool Prop { get; set; }
}

对于t1.Prop = t2.Prop = t3.Prop = false;IL 是:

IL_0013:  ldloc.0     //t1
IL_0014:  ldloc.1     //t2
IL_0015:  ldloc.2     //t2
IL_0016:  ldc.i4.0    //false
IL_0017:  dup         //dup the false on the stack
IL_0018:  stloc.3     
IL_0019:  callvirt    UserQuery+Test.set_Prop //set value
IL_001E:  nop         
IL_001F:  ldloc.3     
IL_0020:  dup         //dup the false on the stack
IL_0021:  stloc.3     
IL_0022:  callvirt    UserQuery+Test.set_Prop //set value
IL_0027:  nop         
IL_0028:  ldloc.3     
IL_0029:  callvirt    UserQuery+Test.set_Prop //set value

为了:

t1.Prop = false;
t2.Prop = false;
t3.Prop = false;

IL是:

IL_0012:  stloc.2     
IL_0013:  ldloc.0     
IL_0014:  ldc.i4.0    //false  
IL_0015:  callvirt    UserQuery+Test.set_Prop //set value
IL_001A:  nop         
IL_001B:  ldloc.1     
IL_001C:  ldc.i4.0    //false
IL_001D:  callvirt    UserQuery+Test.set_Prop //set value
IL_0022:  nop         
IL_0023:  ldloc.2     
IL_0024:  ldc.i4.0    //false 
IL_0025:  callvirt    UserQuery+Test.set_Prop //set value

所以 IL 非常接近,真正唯一的区别是命中ldc.i4.03 次,或者命中一次并在堆栈上复制两次。性能无关紧要。但是,如果获得该false值是一项不平凡的操作,则将其放在三行上会花费更长的时间,但是您可以轻松地编写:

bool value = SomeLongOperation();
t1.Prop = value;
t2.Prop = value;
t3.Prop = value;

因此,尽一切可能对公司内的可读性和/或您的标准最有利。

编辑:实际上,如果编译器/JIT 将单独的行条目优化为基本上第一种情况(或更快的情况)或其他一些优化状态,我不会感到惊讶。真的,唯一需要关心的是最后一个代码示例;如果你需要做SomeLongOperation()才能获得价值,只做一次。之后,做任何可读的事情。

于 2012-10-11T11:19:27.173 回答
0

你通常会这样做:

variable1 = varaible2 = variable3 = 123

但是由于该Enable属性是一个吸气剂,所以这是不可能的。在内部,getter 如下所示:

public bool Enabled
{
    get
    {
        return something;
    }
    set
    {
        something = value;
    }
}
于 2012-10-11T11:06:16.273 回答