2010-07-27 43 views
6

Trong C#, tôi có một lớp vectơ 3D đơn giản.C# = toán tử số

static void Main(string[] args) 
{ 
    Vector3D a, b; 
    a = new Vector3D(0, 5, 10); 
    b = new Vector3D(0, 0, 0); 

    b = a; 
    a.x = 10; 

    Console.WriteLine("vector a=" + a.ToString()); 
    Console.WriteLine("vector b=" + b.ToString()); 
    Console.ReadKey(); 
} 

đầu ra là,

vector a = 10, 5, 10

vector b = 10, 5, 10

tôi gán một trước khi tôi thay đổi rìu đến 10 Vì vậy, tôi đã mong

vector a = 10, 5, 10

vector b = 0, 5, 10

Từ những gì tôi hiểu = toán tử gán một tham chiếu đến đối tượng như một con trỏ? Và trong C# i cant overload = operator.

Tôi có phải chỉ định từng thuộc tính theo cách thủ công không?

+5

Cách thực hành tốt nhất ở đây là tạo loại * không thay đổi được, hoặc là loại tham chiếu hoặc loại giá trị, không quan trọng. Vectơ là giá trị * hợp lý *. Khi bạn thêm bốn đến mười hai bạn không logic "biến đổi" hai thành sáu và giữ cho một trong những giống nhau! Bạn tạo một số hoàn toàn mới hoàn toàn. Tương tự như vậy khi bạn thay đổi tọa độ x của một vectơ, bạn không thay đổi tọa độ x và giữ y và z giống nhau: bạn tạo một vectơ hoàn toàn mới. Bạn sẽ thấy rằng bạn có nhiều khả năng hơn lý do về toán học vector nếu bạn xử lý các giá trị dưới dạng giá trị, không phải là trạng thái có thể thay đổi. –

Trả lời

10

Có, vì Vecor3D là một lớp điều này khá chính xác.

Các lớp là các loại tham chiếu và câu lệnh b = a; của bạn không sao chép một cá thể Vector3D mà là một tham chiếu đến một cá thể.

Nếu bạn muốn 'sao chép' các trường hợp, bạn có thể thêm giao diện IClonable, nhưng đó là nhiều hơn hoặc ít bị bỏ rơi.

Giải pháp tốt hơn cho loại <X,Y,Z> có thể là làm cho cấu trúc trở thành cấu trúc. Structs là các kiểu giá trị và ý nghĩa của b = a; sẽ thay đổi (theo hướng bạn muốn).

Điểm 3D đáp ứng tất cả các tiêu chí cho cấu trúc (nhỏ, không có nhận dạng). Cách ưu tiên là thiết kế nó như là bất biến.

+0

Sau đó, tôi phải gán từng thuộc tính theo cách thủ công? – Kayhano

+0

@Kayhano: Nếu bạn muốn nó là một lớp học, vâng. Nhưng xem phiên bản cuối cùng, ý tưởng tốt nhất là làm cho nó trở thành một cấu trúc. –

+0

Nếu bạn làm cho nó một cấu trúc, nó sẽ làm việc như bạn mong đợi. – ConsultUtah

2

Có, các loại tham chiếu được phân tích theo tham chiếu.

Nếu bạn muốn có một phiên bản riêng biệt, bạn muốn CLONE ví dụ của bạn.

Tạo một phương pháp Vector3D.Clone(), trong đó sẽ giống như thế này:

public Vector3D Clone() 
{ 
    return new Vector3D(this.x, this.y, this.x); 
} 

Sau đó, chính bạn sẽ trông như thế này:

static void Main(string[] args) 
{ 
    Vector3D a, b; 
    a = new Vector3D(0, 5, 10); 
    b = new Vector3D(0, 0, 0); 

    b = a.Clone(); 
    a.x = 10; 

    Console.WriteLine("vector a=" + a.ToString()); 
    Console.WriteLine("vector b=" + b.ToString()); 
    Console.ReadKey(); 
} 

Nhưng như những người khác đã nói, một cái gì đó như nhỏ như một Vector3D sẽ phù hợp hơn với cấu trúc không thay đổi

2

Bạn có thể muốn thay đổi lớp Vector3D thành cấu trúc. Điều đó sẽ cho phép bạn làm việc với một loại giá trị thay vì loại tham chiếu.

Tùy chọn khác của bạn là triển khai ICloneable hoặc sử dụng một số phương pháp khác để tạo bản sao sâu của đối tượng của bạn.

+0

Arent các loại Vector trong XNA tất cả 'struct'? –

+0

@ Allen: Tôi đã không chơi với XNA ở tất cả, vì vậy tôi không thể nói cho bạn biết. Đoán của tôi sẽ là họ đang có, tuy nhiên. – AllenG

+0

yep, chúng là :) http://msdn.microsoft.com/en-us/library/bb196942(v=XNAGameStudio.40).aspx –

3

Có, "= toán tử gán tham chiếu đến đối tượng như con trỏ", khi bạn đặt. Do đó, cả hai số ab đều tham chiếu cùng một đối tượng đơn trong bộ nhớ.(Các đối tượng trước đây được tham chiếu bởi b không tham chiếu nữa và sẽ được thu gom rác.)

Có nhiều cách để khắc phục vấn đề này:

  1. Hãy Vector3D một struct thay vì một lớp. Structs là giá trị loại thay vì loại tham chiếu, do đó, b = asao chép nội dung của a thành biến b.

  2. Thực hiện phương thức Clone trong lớp Vector3D của bạn (trước đây, điều này có nghĩa là triển khai ICloneable, nhưng this is no longer recommended). Ngoài ra, bạn có thể tạo một hàm tạo Vector3D lấy một vectơ khác làm tham số và tạo bản sao.

  3. Sao chép thủ công ba giá trị (b = new Vector3D(a.x, a.y, a.z)) theo cách thủ công, nếu bạn không thể thay đổi việc triển khai Vector3D.

1

Bạn có thể biến nó thành cấu trúc như Henk nói. Và bạn có thể thêm một hàm tạo

struct Vector3D 
{ 
    public int x; 
    public int y; 
    public int z; 

    public Vector3D(int x, int y, int z) 
    { 
     this.x = x; 
     this.y = y; 
     this.z = z; 
    } 
    public override string ToString() 
    { 
     return string.Format("{0}, {1}, {2}", x, y, z); 
    } 
} 

Bạn cũng có thể làm điều này mà không cần thêm hàm tạo.

b = new Vector3D() {x=0, y=0, z=0}; 
0

Không cần phải sử dụng một struct, tôi đề nghị bạn nên thiết kế Vector3D như một bất biến lớp học của bạn. Here là một số ví dụ hay. Tất nhiên, a.x = 10 sẽ không thể thực hiện cho một lớp học bất biến.