2012-01-23 17 views
5

Tôi đang tạo một Instance động bằng Activator.CreateInstance. Tuy nhiên, nó đang nói đối tượng không thể được null trên mọi nỗ lực. Dán mã bên dưới. Tôi có làm gì sai không?Activator.CreateInstance không

Có bất kỳ vấn đề nếu

Activator.CreateInstance

thay thế công tắc/trường hợp báo cáo thông thường để xác định loại đối tượng trong thời gian chạy? Cảm ơn.

public abstract class Base 
{ 
    public abstract void Func(); 

} 
public class Derived:Base 
{ 
    public override void Func() 
    { 
     MessageBox.Show("Derived First"); 
    } 
} 

public class Derived2 : Base 
{ 
    public override void Func() 
    { 
     MessageBox.Show("Derived Second"); 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    // I was trying to make use of the overladed version 
    // where it takes the Type as parameter. 
    BaseClass report = 
     (BaseClass) Activator.CreateInstance(Type.GetType("Derived")); 
    report.Func(); 
} 
+0

tại sao bạn không sử dụng typeof() thay vì Type.GetType() ?? –

Trả lời

3

Từ các tài liệu của typeName tham số của Type.GetType:

Tên lắp ráp đủ của các loại để có được. Xem AssemblyQualifiedName. Nếu kiểu này hiện đang trong quá trình thực thi hoặc trong Mscorlib.dll, đủ để cung cấp tên kiểu đủ điều kiện theo không gian tên của nó.

Điều này có nghĩa rằng bạn cần phải (ít nhất) vượt qua không gian tên cũng như:

BaseClass report = (BaseClass) Activator.CreateInstance(Type.GetType("YourNamespace.Derived")); 
1

Phương thức GetType không thành công và trả về giá trị rỗng. Xem phần tham số của liên kết trước.

Tên hội đủ điều kiện của loại để nhận. Xem AssemblyQualifiedName. Nếu kiểu này nằm trong assembly đang thực thi hoặc trong Mscorlib.dll, thì nó đủ để cung cấp tên kiểu có đủ điều kiện theo không gian tên của nó.

Thêm không gian tên trước "Derived" và nếu lớp Derived là trong một hội đồng khác nhau, sau đó thêm ", assemblyname" đến cùng.


Lưu ý rằng nếu bạn sẽ không thay đổi chuỗi bạn vượt qua thành GetType, sau đó bạn có thể chỉ cần sử dụng typeof(Derived) (mặc dù trong trường hợp đó không có nhiều điểm sử dụng Activator.CreateInstance).

3

Vâng, Type.GetType("Derived") là gần như chắc chắn trở về null - mà sẽ làm cho nó không có gì để làm với Activator.CreateInstance.

Kiểm tra:

  • Derived trong lắp ráp giống như mã số gọi điện thoại? Nếu không, hãy sử dụng Assembly.GetType trên lắp ráp phù hợp hoặc bao gồm tên lắp ráp trong tên loại mà bạn đang chuyển đến Type.GetType()
  • Loại của bạn có nằm trong không gian tên không?Nếu vậy, bạn cần phải không gian tên đủ điều kiện nó
+0

Có vấn đề gì nếu phương pháp này thay thế các câu lệnh chuyển đổi/trường hợp thông thường để xác định loại đối tượng trong thời gian chạy? Cảm ơn. – logeeks

+0

@logeeks: Nó không thực sự rõ ràng những gì bạn có nghĩa là, phải trung thực. –

+0

Trong chương trình của tôi, tôi nhận được một giá trị enum từ máy chủ. giá trị enum đó sẽ xác định đối tượng nào cần được tạo. ví dụ: Mammal mb; switch (MammalType): case Cat: mb = new Cat(); phá vỡ; trường hợp Dog: mb = new Dog(); Tôi đã hỏi nếu tôi bằng cách nào đó có thể lấy tên của giá trị enum, tôi có thể sử dụng nó xây dựng các đối tượng lớp trong một tuyên bố duy nhất chứ không phải là tùy thuộc vào tuyên bố trường hợp chuyển đổi. Cách tiếp cận này có bất kỳ hạn chế nào không? – logeeks

3

Type.GetType("Derived" không thể tìm thấy các loại

Simeple thay đổi

BaseClass report = (BaseClass) Activator.CreateInstance(Type.GetType("Derived")); 

này

Base report = (Base)Activator.CreateInstance(typeof(Derived)); 
+1

Trong trường hợp đó, tôi đoán 'Base report = new Derived();' sẽ đơn giản hơn? –

+0

Có, nhưng tôi nghĩ câu hỏi này chỉ là một mẫu. – dknaack

+2

Tôi cũng nghĩ như vậy, nhưng tôi cũng nghĩ rằng điểm mấu chốt là loại không biết lúc biên dịch. Nếu nó là (như trong câu trả lời của bạn), không cần sử dụng 'Activator.CreateInstance' chút nào. –

0

Tại Runtime, gọi GetType của bạn sẽ trả lại null. Bạn cần phải:

  • hoặc chính xác không gian tên của bạn
  • hoặc Sử dụng typeof
Các vấn đề liên quan