2012-04-10 42 views
7

Tôi muốn hạn chế tạo đối tượng bằng cách sử dụng hàm tạo mặc định. Bởi vì tôi có một desing như dưới đây:Thiết kế không có hàm tạo mặc định

class Program 
{ 
    static void Main(string[] args) 
    { 
     BaseClass bc = new BaseClass("",""); 
     XmlSerializer xml = new XmlSerializer(typeof(BaseClass)); 
     StreamWriter sw = new StreamWriter(File.Create("c:\\test.txt")); 
     xml.Serialize(sw,bc); 
     sw.Flush(); 
     sw.Close(); 
    } 
} 
[Serializable] 
public class BaseClass 
{ 
    public string UserName, Password; 
    // I don't want to create default constructor because of Authentication 
    public BaseClass(string _UserName, string _Password) 
    { 
     UserName = _UserName; 
     Password = _Password; 
     f_Authenticate(); 
    } 
    private void f_Authenticate() { } 
} 

public class DerivedClass:BaseClass 
{ 
    public DerivedClass(string _UserName, string _Password) : base(_UserName, _Password) 
    { 
    } 
} 

Điều này là ok. Nhưng khi tôi làm BaseClass để Serializable nó sẽ tạo ra lỗi này: Unhandled Exception: System.InvalidOperationException: ConsoleApplication1.BaseC lass cannot be serialized because it does not have a parameterless constructor.

Bây giờ thiết kế của tôi đang sụp đổ vì tôi cần phải có Username, Password thông số nhưng constructor mặc định là làm hỏng thiết kế của tôi ....

gì tôi nên làm gì?

+0

Thực ra tôi muốn tìm hiểu mọi khả năng. nếu tôi có thể/không thể sử dụng những gì bạn sẽ cung cấp cho tôi? – uzay95

+0

Bản sao của http://stackoverflow.com/questions/267724/why-xml-serializable-class-need-a-parameterless-constructor – Matten

Trả lời

12

Tạo một constructor mặc định riêng

private DerivedClass() 
{ 
    // code 
} 

Các serialzer sẽ gọi thành công này mặc dù nó tin

+0

Không, bởi vì nó đòi hỏi một hàm tạo mặc định, do đó nó sẽ được truy cập công khai. –

+1

@TomWijsman Rõ ràng là không, xem bình luận về câu trả lời của Matten – Robbie

+1

Và hoàn toàn toàn diện, bạn có thể thêm [Obsolete ("Default constructor chỉ dành cho serialization!", True)] vào hàm tạo riêng đó, để đảm bảo bạn không vô tình gọi nó từ bên trong lớp. – yoyo

11

Lớp deserializing trường hợp của bạn đòi hỏi một constructor parameterless để tạo ra các ví dụ, nhưng bạn không có để triển khai một hàm tạo công khai - đủ để có một hàm tạo private hoặc internal miễn là nó không cần tham số.

Nhân tiện, bạn cũng có thể sử dụng DataContractSerializer, không yêu cầu một hàm tạo tham số và cũng tạo XML; đó luôn là lựa chọn chính của tôi :-)

+1

Nó sử dụng sự phản chiếu – Matten

+0

Tôi không nhận ra điều này sẽ hợp lệ? Tôi mong đợi nó cần một nhà xây dựng công cộng. Điều này chắc chắn có hiệu quả không? Nếu vậy, mát mẻ! – Liam

+0

@TomWijsmanno, không, ý tôi là gọi hàm khởi tạo không mặc định (trong ví dụ của OP), nhưng tôi đã xóa câu trả lời/nhận xét của mình khi nhận ra rằng đó là trình nối tiếp gọi hàm khởi tạo mặc định và do đó nó không thể là riêng tư (tôi đoán) – Robbie

1
  • Bạn đã cố tạo một hàm tạo không tham số riêng tư?

  • Nếu có nhu cầu một công cộng, bạn luôn có thể bình luận nói rằng nó không nên được sử dụng (không phải là giải pháp tốt nhất)

Bạn cũng cần phải tạo thuộc tính trong lớp Serializable của bạn. Các biến không được xem xét và sẽ không được đọc hoặc viết trong quá trình tuần tự hóa/deserealization

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