2010-12-01 2 views
3

Есть ли какие-либо преимущества в производительности от передачи объектов, таких как WebControls, по ссылке? Я специально думаю о таких вещах, как методы проверки, которые изменяют внешний вид элемента управления & feel (background-color, CSSClass и т. Д.) ...Преимущества, полученные при передаче WebControls по ссылке

ответ

7

Nope. Единственное преимущество передачи переменной ссылочного типа по ссылке - это то, что вы хотите изменить значение переменной вызывающего, т. Е. Изменить тот объект, на который он ссылается. Например:

// Creates a new label if necessary, and sets the text to Stuff 
public void Foo(ref Label label) 
{ 
    if (label == null) 
    { 
     label = new Label(); 
    } 
    label.Text = "Stuff"; 
} 

Лично я стараюсь избегать ref, где это возможно: он стремится указать, что этот метод делает слишком много.

+0

@Jon, я что-то не хватает? Если это ссылочный тип, почему бы вам никогда не потребовалось передать его `ref`? Разве пример, который вы не дали, отлично работает без `ref`? – Brad 2010-12-01 14:36:19

+0

@Brad: Нет, это не так ... потому что, если переменная вызывающего была пустым, она была бы пустой, если бы вы не использовали ref. См. Http://pobox.com/~skeet/csharp/parameters.html – 2010-12-01 14:37:07

+0

@JonSkeet - отличная статья, большое спасибо. – 5arx 2010-12-01 14:55:22

1

Нет, никаких преимуществ при работе.

Как это уже ссылочные типы, это не нужно и только сделает ваш код более громоздким, чтобы писать и использовать.

2

Когда вы делаете

Button btn = new Button(); 

переменная БТН не вновь созданной кнопки, вместо того, чтобы это ссылка на эту кнопку. Так что, если я хочу, чтобы иметь метод, который делает кнопки текст жирным шрифтом, это достаточно:

public void MakeButtonBold(Button button) 
{ 
    button.Font.Bold = true; 
} 

, потому что, даже если метод использует передачу по значению, я получаю копию ссылки на кнопку , Затем, когда я разыгрываю его с помощью оператора ., объект, который я получаю, тот же, поскольку и ссылка вне метода, и его копия в методе указывает на тот же объект.

Однако, если я что-то вроде этого

public void ReplaceButtonWithBold(Button button) 
{ 
    button = new Button(); 
    button.Font.Bold = true; 
} 

это не будет работать, потому что я отбрасываюсь переданной ссылка, когда я установил его на новую кнопку.

В отличие от этого, когда я использую параметр ref, создается ссылка на переменную, которая используется для параметра, и эта ссылка передается методу. Поэтому, если ReplaceButtonWithBold использовал параметр ref, мой код работал бы по назначению.

Итак, эмпирическое правило должно быть только для использования параметров ref, если вы явно хотите заменить полностью переданным объектом с чем-то другим, а не когда вы хотите изменить некоторые свойства. С точки зрения производительности нормальный метод должен сделать копию ссылки, а метод ref должен сделать новую ссылку на исходную ссылку, поэтому в любом случае вам нужно использовать время и память для создания и управления ссылкой

1

это крайне маловероятно, чтобы это никогда не имеет значения, но ниже приведен код, я играл с, чтобы проверить это:

public class popo 
{ 
    public int X; 
    public int Y; 
} 

public static bool foo(popo x) 
{ 
    x.X = 10; 
    return x.X == x.Y; 
} 

public static bool foo(ref popo x) 
{ 
    x.X = 10; 
    return x.X == x.Y; 
} 

static void Main(string[] args) 
{ 
    Stopwatch sw = new Stopwatch(); 
    sw.Stop(); 
    sw.Reset(); 
    sw.Start(); 
    popo pio = new popo(); 
    bool luka = true; 
    for (long i = 0; i < 100000000; ++i) 
    { 
     luka = luka^foo(pio); 
    } 
    sw.Stop(); 
    Trace.WriteLine(sw.ElapsedMilliseconds); 
} 

Результаты (в миллисекундах):

Release Val: 948 
Release Ref: 1065 
Debug Val: 2451 
Debug Ref: 2550 

Очевидно, что это не реально код. Могут быть ситуации, когда передача ссылочного типа по ссылке выполняется быстрее. Бывают случаи, когда использование более быстрого процессора может замедлить работу приложения.Тем не менее, это дает быстрый и грязный намек на то, что ref, вероятно, будет немного медленнее. Он также демонстрирует, что это не имеет значения: посмотрите, сколько итераций мне нужно было увидеть даже в 100 мс разницу во времени выполнения.

Очень маловероятно, что эффективность ref и ценность для классов будут иметь отношение к вашему коду.

Смежные вопросы