2014-10-17 46 views
5

我的目標是在控制檯應用程序的ConfigurationManager.ConnectionStrings集合上使用LINQ Where查詢(假設添加了System.Configuration引用的新的.NET 4.5控制檯應用程序,以及對應的聲明)。使用LINQ凡查詢只獲得一些ConfigurationManager.ConnectionStrings

我開始用這個,這確實工作

var relevantSettings = 
     ConfigurationManager.ConnectionStrings.Where(s => s.Name.StartsWith("Xyz")); 

它告訴我說:

The type arguments for method ' IEnumerable<TSource> System.Linq.Enumerable.Where<TSource(this IEnumerable<TSource>, Func<TSource,bool>) ' cannot be inferred from the usage. Try specifying the arguments explicitly.

這抓住了我措手不及,所以我想這個檢查我理智,但這是不是工作要麼:

foreach (var settingsin ConfigurationManager.ConnectionStrings) 
{ 
    if (settings.Name.StartsWith("Xyz")) Console.WriteLine("Found one!"); 
} 

它抱怨有關foreach聲明,但有關.Name位,與錯誤:

Could not resolve symbol 'Name'

據我瞭解,有可能是一些防止編譯器推斷var的類型,來仔細檢查我試過這個確實工作

foreach (ConnectionStringSettings settings in ConfigurationManager.ConnectionStrings) 
{ 
    if (connectionString.Name.StartsWith("Xyz")) Console.WriteLine("Found one!"); 
} 

但是,除了解決我眼前的問題,這並沒有什麼幫助。我想瞭解這裏發生了什麼事情。

我想要做的就是使用一個簡單的LINQ Where語句在我的app.config中獲取連接字符串的子集。爲什麼編譯器阻止我這樣做?

回答

13

TL; DR版

你需要做一個.Cast<ConnectionStringSettings>(),使這項工作。

詳細

好吧,如果你挖連得更深一些,你可以讓編譯器告訴你更多:

Func<ConnectionStringSettings, bool> StartsWithXyz = c => c.Name.StartsWith("Xyz"); 
var relevantSettings = ConfigurationManager.ConnectionStrings.Where(StartsWithXyz); 

這是告訴你:

Cannot convert instance argument type ' System.Configuration.ConnectionStringSettingsCollection ' to ' System.Collections.Generic.IEnumerable<System.Configuration.ConnectionStringSettings> '

駕駛繼承樹的ConnectionStringSettings屬性,你終於可以看到罪魁禍首,這使得很多道理:屬性是通用IEnumerable類型

這實際上使問題成爲this question的一個相當複雜的重複,因爲解決方案在於將非泛型屬性轉換爲泛型列表,以便LINQ和編譯器可以發揮它們的魔力。對於這種特殊的情況下,以下確實工作

var relevantSettings = ConfigurationManager.ConnectionStrings 
              .Cast<ConnectionStringSettings>() 
              .Where(c => c.Name.StartsWith("Xyz")); 

享受!

+1

+1不僅是[that](http://stackoverflow.com/q/776397/419956)的副本,還有[this](http://stackoverflow.com/questions/26414317/system-data -datarowcollection-does-not-contain-a-definition-for-tolist-and-no)我已經在9小時前回答了。基本上這是因爲這些類比C#中的泛型更古老。 – 2014-10-17 07:09:50

+0

是的,我想可能會有更多的重複,一旦你明白了這個問題,很容易發現它們。我用「問題問題」功能作爲橡皮鴨,幫助我找到答案。我想我的文本*可能會幫助其他人*搜索這個問題的具體實例,並且因爲似乎沒有關於'ConnectionStrings'的一個,所以我反正發佈了它。 – Jeroen 2014-10-17 07:15:05

+0

這並不意味着批評。在這種情況下,他們不明白爲什麼他們不讓[課程](http://msdn.microsoft.com/en-us/library/system.configuration.configurationelementcollection%28v=vs.80%29.aspx)實施'IEnumerable ',因爲它也是從.NET 2.0引入的泛型。我想他們在那個階級出生的時候還沒有完成, – 2014-10-17 07:24:09