2015-01-29 4 views
0

Я создал класс, который передает строковый параметр в конструкторе. Я изменяю значение параметра в конструкторе. Когда элемент управления возвращается в исходный класс, значение не изменяется. Я ожидаю, что это изменить - пожалуйста, помогитеC# Передача параметра по значению

 string NewNodeName = ""; 
     AddNode NewNodeFrm = new AddNode(NewNodeName); 

     NewNodeFrm.ShowDialog(); 
     if (NewNodeFrm.DialogResult.Equals(true)) 
     { 
      MessageBox.Show(NewNodeName); 
     } 

В классе называется

public partial class AddNode : Window 
{ 
    private string NodeName; 

    public AddNode(ref string ANodeName) 
    { 
     NodeName = ANodeName; 
     NodeName = "Fred"; 

     InitializeComponent(); 
    } 
+1

'DialogResult.Equals (true)' - это странно, откуда вы это узнали? – Sinatr

+2

Когда вы вызываете метод с параметром 'ref', он должен жаловаться, если вы также не звоните с' ref' ...? Кроме того, вы не назначаете 'ANodeName'. – crashmstr

+3

Кстати, очень необычно иметь конструктор, который мутирует входящие параметры/переменные. Конструктор должен построить/инициализировать экземпляр нового объекта, а не мутировать другие объекты! – stakx

ответ

2

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

NodeName = ANodeName; 

Вы создаете копию, а не ссылку.

Если вы сделали что-то вроде этого:

 Foo NewNodeName = new Foo(); 
     AddNode NewNodeFrm = new AddNode(ref NewNodeName); 
     MessageBox.Show(NewNodeName.ToString()); 

И:

public class Foo 
    { 
     private int _a = 0; 

     public int BAR { get { return _a; } set { _a = value; } } 
    } 

    public class AddNode 
    { 
     private Foo NodeName; 

     public AddNode(ref Foo ANodeName) 
     { 
      NodeName = ANodeName; 
      NodeName.BAR = 30; 
     } 
    } 

Тогда это было бы хорошо, изменения будут видны вызывающему абоненту, так как вы работаете на одном объекте в методе AddNode. На самом деле вам не нужно использовать ключевое слово «ref» (передать по ссылке) в этом случае, поскольку мы не создаем новый экземпляр Foo в методе AddNode.

+0

Тот факт, что строка «действует как тип значения» для этого вообще не имеет значения. Если бы вы работали с объектами, выполняющими 'NodeName = ANodeName; NodeName = new object() 'все равно не повлияет на« ANodeName ». –

+0

Он ожидал, что NewNodeName вернется из метода AddNode с помощью «Fred». Я делаю OP осознающим, что этого не произойдет из-за нового строкового экземпляра, когда присваивается «NodeName = ANodeName»; сделан. – Jeb

+0

Я знаю это, но это событие не имеет ничего общего с объектом, с которым вы работаете, с ссылочным типом или типом значения. –

4

Когда вы пишете NodeName = "Fred"; вы меняетесь, что NodeName имеет в виду. Это потому, что NodeName сам по себе не является ref string.

0

Вы можете преодолеть использование объекта. Может быть, пройдет в этом:

Public class NodeName 
{ 

     public string Name{get;set;} 

} 

Затем в конструкторе установить локальную переменную и изменить имя

public AddNode : Window 
{ 
    Private NodeNme name; 
    Public AddNode(NodeNme name) 
    { 
     this.name = name; 
     this.name.Name = "Fred"; 
    } 
} 

Поскольку ваш проезжают и хранение тип реф это будет отражать изменения внутри вашего класса, так и в вашего потребителя.

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