2010-04-07 25 views
7

Hãy có một ví dụ sau:Namespace scoped bí danh với nhiều loại generic trong C#

public class X { } 
public class Y { } 
public class Z { } 

public delegate IDictionary<Y, IList<Z>> Bar(IList<X> x, int i); 

public interface IFoo 
{ 
    // ... 
    Bar Bar { get; } 
} 

public class Foo : IFoo 
{ 
    // ... 
    public Bar Bar 
    { 
     get 
     { 
      return null; //... 
     } 
    } 
} 

void Main() 
{ 
    IFoo foo; //= ... 
    IEnumerable<IList<X>> source; //= ... 
    var results = source.Select(foo.Bar); // <- compile error here 
} 

Trình biên dịch nói:

Những lập luận kiểu cho phương pháp 'System.Linq.Enumerable.Select (Hệ thống .Collections.Generic.IEnumerable, System.Func) 'không thể được suy ra từ mức sử dụng. Hãy thử chỉ định các đối số loại một cách rõ ràng.

Đó là vì, nó không thể chuyển đổi Bar thành Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

Sẽ thật tuyệt nếu tôi có thể tạo bí danh loại phạm vi kiểu không gian tên cho các loại chung trong C#. Sau đó, tôi sẽ xác định Bar không phải là một đại biểu, nhưng thay vào đó tôi sẽ xác định nó như là một bí danh phạm vi không gian tên cho Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

public alias Bar = Func<IList<X>, int, IDictionary<Y, IList<Z>>>; 

Sau đó tôi có thể xác định bí danh phạm vi không gian tên cho ví dụ: IDictionary<Y, IList<Z>>.

Và nếu được sử dụng một cách thích hợp :), nó sẽ làm cho mã dễ đọc hơn. Bây giờ, tôi phải nội tuyến các loại chung chung và mã thực không thể đọc được: (

Bạn có gặp rắc rối tương tự không :)? Có lý do chính đáng nào tại sao nó không có trong C# 3.0 không? Hoặc không có lý do chính đáng, nó chỉ là vấn đề tiền bạc và/hoặc thời gian?

EDIT: Tôi biết rằng tôi có thể sử dụng using, nhưng nó không phải là không gian tên phạm vi - không thuận tiện cho trường hợp của tôi.

EDIT2: Xem comment by Joren nơi ông đề xuất rằng việc nhập cấu trúc cũng có thể giải quyết được sự cố.

+0

Tôi không chắc vấn đề với 'using' là - được cấp nó không định nghĩa một kiểu mới, nhưng không phải là những gì bạn muốn? –

+0

Như tôi đã viết, nó không phải là không gian tên scoped, nhưng thay vì tập tin scoped. Tôi cần sử dụng bí danh trên các tệp cs và các hội đồng. –

Trả lời

8

Bạn đang trên may mắn; chỉ thị sử dụng chỉ ảnh hưởng đến tệp hiện tại của nó. Không có cơ chế bí danh loại không gian tên.

Đây là một tính năng khá thường xuyên được yêu cầu, đó là điểm cho nó. Nhưng nó cũng là một tính năng tiện lợi "tốt để có" thay vì một tính năng thực sự bổ sung nhiều sức mạnh biểu diễn cho ngôn ngữ, đó là điểm chống lại nó. Nó sẽ được tốt đẹp để làm, nhưng nó không thực sự cao trong danh sách ưu tiên.

+1

Nếu tôi không nhầm, việc gõ cấu trúc trên các đại biểu cũng có thể cho phép trình biên dịch xử lý tình huống cụ thể này, mặc dù theo một cách rất khác.Có cơ hội hợp lý nào hỗ trợ cho việc gõ cấu trúc cho những thứ như đại biểu đôi khi sẽ được thực hiện? – Joren

+0

@ Joren: Vâng, điều đó sẽ giải quyết vấn đề này. Tôi nghĩ rằng hầu hết mọi người bây giờ nhận ra rằng nó có thể đã được tốt hơn để có cấu trúc gõ vào đại biểu từ đầu, nhưng con tàu đã đi thuyền. Nó sẽ là một thay đổi khá lớn để thay đổi nó ngay bây giờ. Điều đó nói rằng, có mối quan tâm mới trong việc đánh máy cấu trúc, vì vậy tôi sẽ không muốn đưa ra tuyên bố rằng có * không * cơ hội xảy ra điều này. –

0

Nếu bạn làm ...

var results = source.Select((x, i) => foo.Bar(x, i)); 

nó có thể tìm ra các loại cho bạn mà không cần phải xác định chúng một cách rõ ràng.

(Phải thừa nhận rằng đây là chi tiết của một công việc xung quanh hơn một giải pháp)

+1

Vâng, tôi biết :) Nó không trả lời câu hỏi của tôi, nhưng cảm ơn :) –