2011-12-31 31 views
6

Tôi đã có hai lớp:Thiết kế khuôn mẫu cho phép chức năng để chấp nhận các loại generic

public abstract class Uniform<T> 
public class UniformMatrix4 : Uniform<Matrix4> 

(Cho đến nay .... sẽ có nhiều mà thực hiện các loại khác nhau)

Và bây giờ cho phép nói Tôi muốn viết một chức năng mà sẽ chấp nhận bất kỳ đối tượng thống nhất ... nhưng tôi không thể làm điều đó bởi vì không có lớp được gọi là Uniform, chỉ có chung Uniform<T>. Vậy cách tiếp cận tốt nhất để giải quyết vấn đề này là gì?

  1. Hãy Uniform<T> thực hiện IUniform
  2. Hãy Uniform<T> mở rộng Uniform
  3. Làm cho tất cả các chức năng của tôi mà chấp nhận một Uniform để được chung chung quá để họ có thể tham gia một Uniform<T> trực tiếp?
+0

phiên bản nào của C# bạn đang sử dụng? Bạn đã xem xét loại động? –

+0

Khi không có lớp được gọi là Đồng phục, làm thế nào có thể tồn tại một đối tượng Đồng phục? –

+0

Nếu không biết gì về mục đích của lớp học, hoặc là chữ ký phương thức trừu tượng, thật khó để đưa ra câu trả lời đúng ở đây. # 3 có vẻ như câu trả lời rõ ràng mặc dù. –

Trả lời

5

Làm cho các phương pháp của bạn trở nên phổ biến, và bạn tốt.

Lưu ý rằng bạn luôn có thể lựa chọn sử dụng tất cả các đối số kiểu chung chung về chức năng, nếu cần thiết, như thế này:

public void MyMethod<TUniform, T>(TUniform uniform) where TUniform: Uniform<T> {...} 

Trình biên dịch thường sẽ suy ra những lập luận kiểu của riêng mình bất cứ khi nào bạn có một tham số, để các cuộc gọi trên thực tế trông giống như một phương pháp gọi bình thường trong mã nguồn # C:

UniformMatrix4 uniform; 
MyMethod(uniform); // the types of the generic functions are inferred 
+0

Đây là những gì tôi muốn làm. Trong Mono dưới Ubuntu 11.10, tôi không thể làm cho nó suy ra các kiểu đối số khá đơn giản và kết thúc bằng một lời gọi xấu: 'Chạy , String> (someClass);' –

+0

@JimSchubert, kiểu suy luận chỉ hoạt động trên các đối số, không phải trên các kiểu trả về, vì kiểu trả về không phải là một phần của chữ ký phương thức (cũng là lý do tại sao bạn không thể có quá tải chỉ khác nhau trong kiểu trả về). Trong những trường hợp đó, bạn phải chỉ định các kiểu, nhưng có một cách giải quyết: làm cho kết quả là một đối số 'out'. – Lucero

+1

Hãy chờ ... tại sao bạn muốn tuyên bố nó như thế này thay vì những gì Domenic gợi ý trong câu trả lời của anh ấy? Điều này có vẻ tiết lộ hơn - lợi ích là gì? – mpen

3

Phải thừa nhận rằng đe dọa để gửi câu trả lời này, nhưng nghĩ rằng nó có thể là đúng:

public static Uniform<dynamic> MyMethod(dynamic myObject) { 
     //do stuff  
     return uniform; 
    } 

Dưới đây là một blog Dino Esposito về chủ đề này:

http://msdn.microsoft.com/en-us/magazine/ff796227.aspx

Chúc mừng,

Matt

+0

Tôi có lẽ không nhận được nó, nhưng làm thế nào là điều này có liên quan? Có lẽ mở rộng trên '// do stuff' sẽ giúp tôi? –

+0

Ôi, nếu bạn tham khảo các trường 'myObject' theo tên, bạn tái tạo chúng thành một' Uniform '? Nếu đó là trường hợp (hay không) có lẽ bạn có thể mở rộng câu trả lời này, tôi khá tò mò? –

+0

Vâng, một lần nữa - một chút hăm dọa góp phần vào cuộc trò chuyện với tất cả các bạn uber danh tiếng, nhưng những gì tôi đã làm là một cái gì đó như thế này: hãy nói rằng tôi muốn sử dụng một phương pháp chung để xây dựng một đối tượng không rõ loại thời gian chạy, tôi sẽ tạo ra một ExpandoObject mới (động myObject = new ExpandoObject();) và sau đó hoặc là điền thuộc tính của nó một cách rõ ràng (myObject.Name = "Matt";) hoặc, trong trường hợp của một truy vấn LINQ, tôi khởi tạo một IDictionary khi looping thông qua các dữ liệu trả về (var item = myObject như IDictionary ; item [SomeKey] = SomeValue;). Cảm ơn. –

2
public void MyMethod<T>(Uniform<T> uniform) { ... } 
+0

Có ... đó là lựa chọn # 3. Bạn có thể giải thích tại sao điều này là thích hợp hơn? Điều tôi không thích về điều này là bạn đang giới thiệu 'T' chỉ được sử dụng một lần trong chữ ký chức năng và sau đó không bao giờ trở lại. Nó sẽ không được sử dụng cho bất cứ điều gì khác – mpen

+2

@Mark, biến kiểu 'T' ở đây là phạm vi cho phương thức, không phải cho lớp. Nó không gây tổn thương chút nào và thường không có thêm chi phí thời gian chạy liên quan đến nó (giả sử rằng 'T' luôn là kiểu tham chiếu). – Lucero

+0

Tôi biết nó đã bị xáo trộn theo phương pháp..chỉ cần nói. Có 3 lựa chọn ở đây và tôi đang cố gắng tìm ra cái nào là tốt nhất. – mpen

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