2010-01-02 3 views
1

Учитывая следующий метод, когда я передаю конфигурацию byref, прокручиваем его с помощью коллекции foreach named. В следующем примере кода значения, которые я изменяю в цикле, будут обновляться в основном объекте, который я прошел через ref, что я имею в виду, это НЕ мелкие копии? Или вы можете обнаружить любую ошибку, которую я совершил.Вопрос теории языка C#

Более конкретно, строка, где я вызываю config.Value = ..... объект конфигурации имеет набор конфигураций, поэтому будут ли они обновляться в основном объекте (конфигурации) после вызова этой функции?

Заранее спасибо.

public static void DecryptProviderValues(ref MyConfiguration configuration) 
    { 
     foreach (var provider in configuration.Providers) 
     { 
      var configItems = provider.Configurations; 
      foreach (Configuration config in configItems) 
      { 
       if(EncryptionManager.IsEncrypted(config.value)) 
       { 
        config.Value = EncryptionManager.Decrypt(config.Value); 

       } 
      } 
     } 
    } 
+0

foreach делает коллекцию неизменной, если обновления коллекции не выполняются после выполнения цикла, как при использовании NHibernate и промывки после того, как мы закончим цикл. Спасибо –

+1

@Mahesh Velaga: коллекция * сама * никогда не изменяется, поэтому, пока это * true *, она не связана. –

+0

@Marc: Я действительно хочу узнать больше об этом, можете ли вы указать мне на хорошую ссылку, касающуюся изменения коллекций в foreach, а также когда они изменяются, а когда нет. Спасибо :) –

ответ

6

Предполагая, что все элементы здесь классов (не структуры), то да, но на самом деле нет никакой необходимости для configuration быть передана как ref; вы уже, передавая ссылку (по значению), и вы не переустанавливаете ссылку, поэтому нет необходимости в ref здесь вообще. Ваши изменения сохранены и доступны для вызывающего.

Для той же самой причине, что это будет работать:

Configuration x = new Configuration(); 
Configuration y = x; 
x.Value = "abc"; 
Console.WriteLine(y.Value); // writes "abc" 

здесь, потому что Configuration это (предположительно) а class, есть только один объект, и две переменные, которые относятся к тому же объект (на упрощенном уровне они прославляют указатели на один и тот же объект).

+0

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

+0

Да. Без 'ref' это все еще доступно. Единственный раз, когда вам понадобится 'ref' (с классами), является если * внутри * метод, который у вас был' configuration = ...; '(т. Е. Вы * переназначили * переменную), и вы хотите, чтобы это переназначение было видимым вызывающего абонента. –

+0

@JL: Да, если это ссылочный тип, поскольку ссылка указывает на экземпляр в куче. Это не имеет никакого значения, если вы обращаетесь к экземпляру через копию самой ссылки. –

2

В вашем случае нет необходимости передавать configurationref, так как в C# вы уже манипулируете ссылками на экземпляры классов.

Вы должны использовать ref для передачи типов значений, таких как int или struct по ссылке.

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