2009-09-09 64 views
5

OK, tiêu đề đó có một chút không rõ ràng, nhưng tôi không thể nghĩ ra một cách tốt hơn để đặt nó, ngoài việc giải thích nó ...Có thể phát hiện ngữ cảnh lớp trong một phương thức tĩnh được kế thừa không?

Giả sử tôi có một lớp Animal, với phương pháp tĩnh, chung:

public static T Create<T>() where T : Animal { 
    // stuff to create, initialize and return an animal of type T 
} 

Và tôi có các lớp con Dog, Cat, Hamster vv để có được một Dog, tôi có thể viết:

Dog d = Animal.Create<Dog>(); 

o r

Dog d = Dog.Create<Dog>(); 

thực sự giống nhau. Nhưng có vẻ hơi ngớ ngẩn khi phải viết Dog rất nhiều lần, vì tôi đã gọi phương thức tĩnh thông qua lớp con Dog.

Bạn có thể nghĩ ra cách nào thông minh viết một phương pháp Create() trong lớp cơ sở để tôi có thể gọi

Dog d = Dog.Create(); 
Cat c = Cat.Create(); 
Hamster h = Hamster.Create(); 

mà không cần viết một phương pháp Create() trong mỗi lớp con?

Trả lời

10

Bạn có thể đặt lớp Thú y chung.

class Animal<T> where T : Animal<T> 
{ 
    public static T Create() 
    { 
     // Don't know what you'll be able to do here 
    } 
} 

class Dog : Animal<Dog> 
{ 

} 

Nhưng cách lớp Animal biết cách tạo trường hợp của các loại có nguồn gốc?

+2

Có thể bạn sẽ muốn hạn chế 'T' đối với Động vật:' lớp Động vật trong đó T: Động vật ' – dtb

+0

@dtb: Chắc chắn! Đã cập nhật phản hồi, cảm ơn. –

+0

Mã bên trong Create() sẽ gọi các phương thức ảo/trừu tượng, đó là cách nó sẽ tạo ra các thể hiện của các kiểu có nguồn gốc. –

2

Tôi sẽ làm cho lớp trừu tượng Lớp học động bằng phương thức Tạo tĩnh; đó là một điểm khởi đầu cho một nhà máy. Trong thực tế, có vẻ như bạn đang hoàn tác một lớp nhà máy.

Nếu bạn thêm một bản tóm tắt Initialize phương pháp để lớp Thú, phương pháp Tạo trở thành:

public static T Create<T>() where T : Animal { 
    T animal = new T(); //may need a "new" in the declaration 
    animal.Initialize(); //or Create or whatever or you put this logic 
         // in the constructor and don't call this at all. 
    return animal; 
} 
+0

Animal không thể là một lớp tĩnh.Tuy nhiên, nếu bạn muốn ủy quyền việc tạo ra cho từng kiểu dẫn xuất, thì có thể là một ý tưởng hay để tạo ra abstract của Animal và phương thức Initialize abstract thay vì virtual. –

+0

Bắt tốt. Đó không phải là ý định. –

+0

@Romain - vâng, tôi đã điều chỉnh câu trả lời của mình. –

1

Bên cạnh những câu trả lời khác về cách xung quanh nó, bạn có thể thấy sử dụng phản ánh rằng Tạo sẽ luôn vẫn là một phần của Animal, không phải là lớp dẫn xuất.

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