Cách tốt nhất để viết hàm khởi tạo bản sao chung cho các lớp C# của tôi là gì? Tất cả đều được thừa hưởng từ một lớp cơ sở trừu tượng để tôi có thể sử dụng sự phản chiếu để ánh xạ các thuộc tính, nhưng tôi tự hỏi nếu có cách nào tốt hơn?Generic C# Copy Constructor
Trả lời
Bạn có thể tạo bản sao nông hiệu quả với sự phản ánh bằng cách biên dịch trước, ví dụ: Expression
. Ví dụ: like so.
Đối với các bản sao sâu, tuần tự hóa là cách tiếp cận đáng tin cậy nhất.
Tránh phản ánh nếu có thể. Mỗi lớp phải có trách nhiệm sao chép các thuộc tính của riêng nó và gửi nó thêm vào phương thức cơ bản.
vì vậy chỉ cần làm rõ, nó muốn được tốt nhất nếu bạn đã có một bản sao constructor tùy chỉnh trên mỗi lớp ánh xạ một cách rõ ràng các thuộc tính? – lomaxx
Tôi muốn. Làm thế nào là khó để viết? Rõ ràng dễ đọc hơn trong nháy mắt hơn là một phương pháp dựa trên sự phản chiếu. – duffymo
Có, tôi muốn giới thiệu phương pháp đó. –
Trình tạo bản sao cơ bản có nghĩa là bạn có một tham số duy nhất, là đối tượng bạn sẽ sao chép.
Ngoài ra, hãy làm một bản sao sâu, không phải bản sao nông.
Nếu bạn không biết những gì bản sâu và nông cạn là, sau đó đây là thỏa thuận:
Giả sử bạn đang sao chép một lớp học có một hàng duy nhất của các số nguyên như lĩnh vực.
Một bản sao cạn sẽ là:
public class Myclass()
{
private int[] row;
public MyClass(MyClass class)
{
this.row = class.row
}
}
bản sao sâu là:
public class Myclass()
{
private int[] row;
public MyClass(MyClass class)
{
for(int i = 0; i<class.row.Length;i++)
{
this.row[i] = class.row[i];
}
}
}
Một bản sao sâu thực sự được các giá trị actuall và đặt chúng trong một lĩnh vực mới của đối tượng mới, trong khi một bản sao nông chỉ sao chép các con trỏ.
Với bản sao cạn, nếu bạn thiết lập:
row[3] = 5;
Và sau đó in cả hai hàng, cả hai bản in sẽ có 5 như giá trị của số 4. Tuy nhiên, với bản in sâu, chỉ in đầu tiên sẽ có điều này, vì các hàng không có cùng một con trỏ.
Bạn có thể sử dụng 'row.clone()' như C# cho phép các mảng nguyên thủy được nhân bản. –
Mã trên không thành công do 'hàng' chưa bao giờ được khởi tạo? – AnotherParker
Đây là một hàm tạo mà tôi đang sử dụng. Lưu ý rằng đây là một hàm tạo cạn, và khá đơn giản, do bản chất của lớp cơ sở của tôi. Nên đủ tốt để giúp bạn bắt đầu.
public partial class LocationView : Location
{
public LocationView() {}
// base class copy constructor
public LocationView(Location value) {
Type t = typeof(Location);
PropertyInfo[] properties = t.GetProperties();
foreach (PropertyInfo pi in properties)
{
pi.SetValue(this, pi.GetValue(value, null), null);
}
}
public Quote Quote { get; set; }
}
Một dòng có thể: 'foreach (var propertyInfo trong typeof (LocationView) .BaseType.GetProperties()) propertyInfo.SetValue (this, propertyInfo.GetValue (obj_to_copy_parameter, null), null);' bạn cũng có thể sử dụng một trình khởi tạo trường để chỉ đọc GetProperties một lần. –
@ChrisMarisic Tôi có xu hướng tránh một lớp lót khi nó hi sinh khả năng đọc. – B2K
Xem thêm http://stackoverflow.com/questions/14218989/best-way-to-clone-properties-of-disparate-objects Tôi đã đưa ra một phần mở rộng chung cho các thuộc tính phổ biến nhân bản nông – B2K
Bạn có thể tham khảo valueinjecter và fasterflect NuGet gói và sử dụng:
public class Myclass()
{
private string _property;
public MyClass(MyClass obj)
{
this.InjectFrom(obj.DeepClone());
}
}
+1 cho các ý tưởng gọn gàng trong ví dụ được liên kết của bạn. – Ergwun