2012-06-21 30 views
6

Làm cách nào tôi có thể chuyển đối tượng của "MyClass" (C#) bằng Parameter-by-Value tới một phương thức? Ví dụ:Vượt qua Giá trị bằng C#

MyClass obj = new MyClass(); 
MyClass.DontModify(obj); //Only use it! 
Console.Writeline(obj.SomeIntProperty); 

...

public static void DontModify(MyClass a) 
{ 
    a.SomeIntProperty+= 100;// Do something more meaningful here 
    return; 
} 
+4

Mọi người có thể cho bạn biết sử dụng một 'struct'. Đừng. – SLaks

+0

tải xuống: (CloneExtensions) từ nuget. Nó sẽ mở rộng đối tượng C# với phương thức GetClone() chấp nhận các cờ mà bạn có thể sử dụng để cho biết bạn muốn một bản sao nông. https://www.nuget.org/packages/CloneExtensions/1.2.0 – alsafoo

Trả lời

9

Theo loại đối tượng mặc định được chuyển theo giá trị trong C#. Nhưng khi bạn vượt qua một đối tượng đối tượng tham chiếu đến một phương pháp, sửa đổi trong đối tượng được duy trì. Nếu bạn muốn đối tượng của bạn được inmutable, bạn cần phải clone nó.

Để làm điều đó, hãy triển khai giao diện ICloneable trong lớp học của bạn. Dưới đây là một ví dụ giả về cách sử dụng ICloneable:

public class MyClass : ICloneable 
{ 
    private int myValue; 

    public MyClass(int val) 
    { 
    myValue = val; 
    } 

    public void object Clone() 
    { 
    return new MyClass(myValue); 
    } 
} 
+2

Thật không may IClonable không xác định xem bản sao sâu hay nông của nó. Bạn có thể kết thúc (khi sử dụng các lớp bạn không tự viết) vẫn sao chép tài liệu tham khảo ở đâu đó xuống dòng. Và vì nó có trước Generics, ICloneable trả về một đối tượng, vì vậy bạn cần phải cast ... toàn bộ điều này khá xấu xí. – linac

+2

Bạn chỉ cần viết 'return MemberwiseClone();' trong phương thức 'Clone'. –

+0

Tôi giả định rằng lớp mà người dùng cần sao chép là một lớp được viết bằng cách viết mã mẫu. Trong trường hợp này, bạn có thể kiểm soát bản sao bằng cách tạo một đối tượng mới. Tất nhiên bạn cần sao chép các loại được nhúng nếu cần. –

4

Theo mặc định, nó được truyền theo giá trị. Tuy nhiên, bạn đang chuyển tham chiếu đối tượng theo giá trị, có nghĩa là bạn vẫn có thể chỉnh sửa giá trị trong đối tượng.

Để ngăn không cho đối tượng có thể thay đổi, bạn cần phải sao chép đối tượng trước khi chuyển nó vào phương thức của bạn. Điều này sẽ yêu cầu bạn phải thực hiện một số phương pháp tạo một cá thể mới là bản sao của đối tượng ban đầu của bạn, và sau đó truyền vào bản sao.

2
public static void DontModify(MyClass a) 
{ 
    MyClass clone = (MyClass)a.Clone(); 
    clone.SomeIntProperty+= 100;// Do something more meaningful here 
    return; 
} 
1

Bạn có thể tạo phương thức Clone trên đối tượng để chuyển giá trị trả về cho phương thức của mình. C# không thể chuyển kiểu tham chiếu theo giá trị vì vậy đây có thể là một lựa chọn tốt.

public MyClass CreateClone() 
{ 
    return new MyClass() { SomeIntProperty = this.SomeIntProperty }; 
} 
1
class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p1 = new Person() 
     { 
      Name = "Alsafoo", 
      Address = new Address() 
      { 
       City = "Chicago" 
      } 
     }; 

     Person p2 = new Person(p1.Address); 
     p2 = p1.GetClone(CloningFlags.Shallow); 
     p2.Name = "Ahmed"; 
     p2.Address = new Address(){City = "Las Vegas"}; 
     Console.WriteLine("p1 first name: {1} --- p1 city: {2} {0}p2 first name: {3} ---- p2 city: {4}", 
      Environment.NewLine, p1.Name, p1.Address.City, p2.Name, p2.Address.City); 
     Console.ReadKey(); 
    } 
} 
public class Person 
{ 
    public Person() 
    {} 
    public Person(Address a) 
    { 
     Address = a; 
    } 
    public string Name { get; set; } 
    public Address Address { get; set; }   
} 

public class Address 
{ 
    public string City { get; set; } 
} 

Tải phần mở rộng này https://www.nuget.org/packages/CloneExtensions/1.2.0

Các vấn đề liên quan