2012-02-12 35 views
13

Điều này dường như không thể? Vậy công việc tốt nhất là gì? Expando/dynamic?truyền loại ẩn danh sang giao diện?

public interface ICoOrd { 
    int x { get; set; } 
    int y { get; set; } 
}  

...

ICoOrd a = new {x = 44, y = 55}; 

ref:

+0

Tôi chỉ tò mò: bạn đang cố gắng làm điều đó sẽ yêu cầu bạn làm điều này? Nếu bạn biết giao diện, bạn rõ ràng biết chức năng của giao diện, vì vậy bạn có thể triển khai một lớp để cung cấp chức năng đó trong trường hợp bạn không cần loại ẩn danh nữa, vì bạn chỉ có thể tạo một thể hiện của lớp. – xxbbcc

+0

Tại sao bạn muốn bỏ ẩn danh (Bạn không "quan tâm" về thiết kế của nó) vào Giao diện (nghĩa là bạn "quan tâm" về thiết kế của nó)? – gdoron

+2

@gdoron: một giao diện là một điều hữu ích để có, và tôi thấy rằng sử dụng tốt các loại anon (không có LINQ trong trường hợp này) đã đơn giản hóa mã của tôi * và * đã giúp với ý định rõ ràng hơn. Đó là động lực. Chủ yếu là để làm với cấu trúc trung gian. – sgtz

Trả lời

27

Cách giải quyết tốt nhất là tạo và sử dụng loại "được đặt tên" bình thường, thực hiện giao diện.

Nhưng nếu bạn nhấn mạnh rằng loại ẩn danh sẽ được sử dụng, hãy xem xét sử dụng khung proxy giao diện động như ImpromptuInterface.

 var myInterface = new { x = 44, y = 55 }.ActLike<ICoOrd>(); 
+3

+1 cho ImpromptuInterface. Bạn cũng có thể xem Clay (clay.codeplex.com) –

+0

Có vẻ như bạn đã đánh bại thầy Jon Skeet ... – gdoron

+2

+1 không biết điều này đã tồn tại. ty. – sgtz

7

Không, loại vô danh không bao giờ thực hiện các giao diện. dynamic cũng sẽ không cho phép bạn truyền tới giao diện, nhưng sẽ cho phép bạn chỉ truy cập vào hai thuộc tính. Lưu ý rằng các loại ẩn danh là internal, vì vậy nếu bạn muốn sử dụng chúng trên các cụm bằng cách sử dụng dynamic, bạn sẽ cần phải sử dụng InternalsVisibleTo.

+1

+1: ty. Tôi đã làm một ít đọc trên InternalsVisibleTo (MS liên kết bây giờ trong câu hỏi). Điều đó rất hữu ích. Có vẻ một chút lao động. Bạn đã thấy InternalsVisibleTo được sử dụng trong lĩnh vực này chưa? – sgtz

+2

@sgtz: Lao động chuyên sâu? Đó là một thuộc tính duy nhất. Phải mất nhiều công việc hơn một chút nếu bạn đang sử dụng các hội đồng được đánh máy mạnh mẽ, nhưng nếu không thì nó rất đơn giản. Tôi sử dụng nó rất nhiều cho các bài kiểm tra đơn vị. –

+6

@sgtz: InternalsVisibleTo thường được sử dụng để kiểm tra đơn vị; đôi khi bạn muốn thử nghiệm đơn vị của một lớp nội bộ nhưng muốn lắp ráp thử nghiệm là một hội đồng khác nhau. Vì vậy, bạn cung cấp cho việc kiểm tra lắp ráp truy cập vào internals. Nó hiếm khi được sử dụng trong các kịch bản mã sản xuất. Hãy nhớ rằng, các assembly là * versionable *; đó là toàn bộ * điểm * của hội đồng. Trong hầu hết trường hợp, bạn sẽ không muốn * độc lập thay đổi các phiên bản * của hai hội đồng * nhìn thấy nội bộ của nhau *. Nếu bạn có hai hội đồng mà cần phải nhìn thấy mỗi người khác internals, xem xét sáp nhập chúng thành một. –

1

Tôi biết đây là một câu hỏi và câu trả lời cũ nhưng tôi tình cờ gặp phải vấn đề này đối với một số bài kiểm tra đơn vị. Sau đó tôi đã xảy ra với tôi rằng tôi đã làm một cái gì đó như thế này bằng cách sử dụng Moq (facepalm).

Tôi thích các gợi ý khác cho ImpromptuInterface nhưng tôi đã sử dụng Moq và cảm thấy như nó có một lớn hơn sau (đó là ý kiến ​​và không thực tế) sẽ ổn định hơn và được hỗ trợ lâu hơn.

như vậy cho trường hợp này sẽ là một cái gì đó giống như

public interface ICoOrd 
{ 
    int X { get; set; } 
    int Y { get; set; } 
} 

public class Sample 
{ 

    public void Test() 
    { 
     var aCord = new Mock<ICoOrd>(); 
     aCord.SetupGet(c => c.X).Returns(44); 
     aCord.SetupGet(c => c.Y).Returns(55); 

     var a = aCord.Object; 
    } 
} 

EDIT: chỉ cần thêm một cách khác để thử dây, bắt đầu thực hiện nó theo cách này và như nó tốt hơn một chút.

public void AnotherTest() 
{ 
    var aCord = Mock.Of<ICoOrd>(c => c.X == 44 && c.Y == 55); 
    //do stuff with aCord 
} 
Các vấn đề liên quan