2012-02-12 165 views
13

這似乎不可能?那麼最好的解決方法是什麼? Expando /動態?將匿名類型轉換爲接口?

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

...

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

裁判:

+0

我只是好奇:你想做什麼,會要求你這樣做?如果你知道接口,你顯然知道接口有什麼功能,所以你可以實現一個類來提供這種功能,在這種情況下你不需要匿名類型,因爲你可以創建一個類的實例。 – xxbbcc 2012-02-12 14:48:38

+0

爲什麼你想要匿名(你不關心它的設計)到一個接口(這意味着你「關心」它的設計)? – gdoron 2012-02-12 14:48:43

+2

@gdoron:一個界面是一個方便的東西,我發現很好地使用匿名類型(在這種情況下沒有LINQ)簡化了我的代碼*和*幫助使意圖更清晰。這是動機。主要是與中間結構有關。 – sgtz 2012-02-12 14:58:02

回答

27

最好的「解決方法」是創建和使用實現接口的普通「命名」類型。

但是,如果您堅持使用匿名類型,請考慮使用動態接口代理框架,如ImpromptuInterface

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

+1爲ImpromptuInterface。你也可以看看粘土(clay.codeplex.com) – 2012-02-12 14:49:03

+0

它看起來像你擊敗了大師Jon Skeet ...... – gdoron 2012-02-12 14:51:18

+2

+1不知道這個存在。 TY。 – sgtz 2012-02-12 14:52:51

7

沒有,匿名類型從未實現的接口。 dynamic也不會讓你投射到界面,但讓你只需訪問這兩個屬性。請注意,匿名類型爲internal,因此如果您想要在使用dynamic的程序集中使用它們,則需要使用InternalsVisibleTo

+1

+1:ty。我在InternalsVisibleTo(現在有問題的MS鏈接)上做了一點點閱讀。這很有幫助。它看起來有點勞動密集。你見過InternalsVisible在現場使用嗎? – sgtz 2012-02-12 15:03:51

+2

@sgtz:勞動密集型?這是一個單一的屬性。如果您使用強類型的程序集,則需要更多的工作,但除此之外它非常簡單。我使用它很多單元測試。 – 2012-02-12 15:22:28

+6

@sgtz:InternalsVisibleTo通常用於單元測試;有時你想對內部類進行單元測試,但希望測試程序集是一個不同的程序集。所以你給測試程序集訪問內部。它很少用於生產代碼場景。請記住,程序集是*可版本*;這是程序集的全部*點*。在大多數情況下,您不希望*獨立更改兩個程序集*的版本,以查看彼此的內部*。如果您有兩個需要查看其他內部組件的組件,請考慮將它們合併爲一個。 – 2012-02-12 15:23:45

1

我知道這是一個古老的問題和答案,但我偶然發現了這個問題,希望對某些單元測試做同樣的事情。然後我發現我已經在用Moq(facepalm)做這種事情了。

我確實喜歡ImpromptuInterface的其他建議,但我已經在使用Moq,覺得它有更大的關注(這是意見而不是事實)會更穩定和支持更長的時間。

所以對於這種情況會是這樣的

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; 
    } 
} 

編輯:只需添加另一種方式來嘲笑線,開始做這種方式和喜歡它更好一點。

public void AnotherTest() 
{ 
    var aCord = Mock.Of<ICoOrd>(c => c.X == 44 && c.Y == 55); 
    //do stuff with aCord 
} 
相關問題