2015-11-05 2 views
0

я следующий код в C#:C# Passing структура в качестве параметра

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
namespace StrParameter 
{ 
    class Program 
    { 
     public struct RVector 
     { 
      private int ndim; 
      private double[] vector; 

      public RVector(int ndim) 
      { 
       this.ndim = ndim; 
       this.vector = new double[ndim]; 
       for (int i = 0; i < ndim; i++) 
       { 
        vector[i] = 0.0; 
       } 
      } 

      public RVector(double[] vector) 
      { 
       this.ndim = vector.Length; 
       this.vector = vector; 
      } 

      public double this[int i] 
      { 
       get 
       { 
        if (i < 0 || i > ndim) 
        { 
         throw new Exception("Requested vector index is out of range!"); 

        } 
        return vector[i]; 
       } 
       set { vector[i] = value; } 
      } 

      public override string ToString() 
      { 
       string str = "("; 
       for (int i = 0; i < ndim - 1; i++) 
       { 
        str += vector[i].ToString() + ", "; 
       } 
       str += vector[ndim - 1].ToString() + ")"; 
       return str; 
      } 
     } 

     static void SwapVectorEntries(RVector b,int m, int n) 
     { 
      double temp = b[m]; 
      b[m] = b[n]; 
      b[n] = temp; 
     } 

     static void Main(string[] args) 
     { 
      double[] a = new double[4] { 1, 2, 3, 4 }; 
      RVector b = new RVector(a); 
      Console.WriteLine(b); 
      SwapVectorEntries(b, 1, 2); //Why after this command, b will be changed ? 
      Console.WriteLine(b); 
     } 
    } 
} 

В этой программе я создаю RVector-структуру. После этого я использую метод SwapVectorEntries, который имеет параметр struct. Потому что Struct - это value type, поэтому я думаю, что метод SwapVectorEntries не изменит параметр struct. Но в программе, после команды SwapVectorEntries(b, 1, 2);, b изменился. Пожалуйста, объясните мне об этом. Спасибо !

+1

Вы не изменяете структуру, вы изменяете массив. Массивы не являются типами значений. Объявление структуры с изменяемым ссылочным типом в качестве поля не является отличной идеей. –

+0

Кроме того, вы можете пропустить инициализацию векторных значений (в 'public RVector (int ndim)' constructor): в C# каждый элемент нового созданного массива будет иметь значение по умолчанию (0.0, в вашем случае с использованием double). Это отличается от C/C++ –

+0

Вы также можете избежать использования переменной-члена 'ndim': вы можете заменить ее' vector.length' каждый раз, когда вам это нужно. –

ответ

2

Проблема в this.You имеют которым массив reference type .Когда вы создаете ваш

double[] a = new double[4] { 1, 2, 3, 4 }; 
RVector b = new RVector(a); 

у вас есть две ссылки на этот array.After, когда вы передаете свой объект в метод,

SwapVectorEntries(b, 1, 2); 

ваш объект копируется, НО ваш новый объект имеют же ссылку на что array.Here ваш есть только один массив и многие относятся к нему.

enter image description here

+0

Но, 'b' является экземпляром структуры' RVector'. Он создается с помощью конструктора с параметром array. Итак, я думаю, что 'b' - тип значения. –

+0

Да b - тип значения. Но когда он копирует как параметр, все его поля также копируются, а beacuse «double [] vector» является ссылкой, это значение (адрес массива) также копирует. Так что у вас есть 2 разные объекты RVector, но они должны быть векторами, которые относятся к одному и тому же объекту. –

+0

Я отредактировал мой asnwer.See there –

2

B сам по себе не передается как ссылка, но копия b имеет ссылку на то же самое double[].

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