2009-09-16 35 views
7

Tôi đang cố gắng xây dựng một phương pháp nhà máy sử dụng tính năng generics của C#.C# Generics - Ràng buộc về các thông số loại

Trong phương pháp nhà máy này, tôi muốn hạn chế nó đối với một số lớp cụ thể, tất cả đều không có hàm tạo mặc định.

Đây là ví dụ của tôi. Ai đó có thể cho tôi biết nếu nó có thể chạy nó?

public class AbstractClass { 
    //this abstract class does not have a default constructor, nor its subclasses 
    public AbstractClass(SomeClassName obj) { 
     //use obj for initialization 
    } 
} 

//this factory class should create objects of type T that inherit 
//from AbstractClass and invoke the non-default constructor 
public class FactoryClass { 
    public static T BuildObject<T> (SomeClassName obj) where T: AbstractClass { 
     return new T(obj); //does not work?!?!?! 
    } 
} 


//Edit: ANSWER!!! 
public static T BuildObject<T>(SomeClassUsedForTheConstructor item) where T : SomeAbstractClass { 
return (T) Activator.CreateInstance(typeof (T), item); 
} 

Trả lời

4

Nhìn vào lớp học Type và GetConstructor. Khi bạn nhận được đối tượng ConstructorInfo, sử dụng phương thức Invoke.

var x = typeof(T); 
var t = x.GetConstructor(new[] {obj.GetType()}); 
object u = t.Invoke(<inputs>); 
+0

Đây là những gì tôi sử dụng để sử dụng, nhưng bây giờ tôi sử dụng 'Activator.CreateInstance' như đã đề cập bởi Brian. –

3

Không, những gì bạn đang cố gắng làm là không thể sử dụng các ràng buộc chung được xây dựng trong một mình. Từ khóa mới chỉ cho phép bạn hạn chế loại chung để có hàm tạo mặc định.

+0

và chỉ khi T: new() được xác định. –

4

Tôi không nghĩ bạn có thể khởi tạo loại chung mà không có a default constructor trên loại ràng buộc.

Hãy xem xét thay vì chỉ định giao diện IAbstractClass, sao cho lớp nhà máy của bạn có thể đặt tham số SomeClassName làm thuộc tính của IAbstractClass.

Ngoài ra, nếu một cá thể SomeClassName là bắt buộc để khởi tạo AbstractClass, hãy xem xét cũng có một hàm tạo mặc định rỗng, nhưng một phương thức khởi tạo phong phú được định nghĩa trong IAbstractClass. Ví dụ:

public interface IAbstractClass { void Initialize(SomeClassName obj); } 

Bằng cách đó, phương pháp BuildObject tĩnh của bạn thay vì thực hiện:

public static T BuildObject<T>(SomeClassName obj) where T: AbstractClass 
{ 
    T newObject = new T(); 
    IAbstractClass ac = newObject as IAbstractClass; 
    ac.Initialize(obj); 
} 
5

Tôi thích sử dụng Activator.CreateInstance(typeof(T)) trong Generics tôi rằng cần phải tạo các đối tượng mới của loại T. Nó hoạt động thực sự tốt.

+0

Điều này sẽ đi vào podcast đá .net! cảm ơn cho câu trả lời. – Pablo

+0

// mã cuối cùng công khai tĩnh T BuildObject (SomeClassUsedForTheConstructor mục) trong đó T: SomeAbstractClass { return (T) Activator.CreateInstance (typeof (T), item); } – Pablo

+2

Rất chậm và không có kiểm tra thời gian biên dịch ... –

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