2014-08-31 61 views
1

我通過解析XDocument的值創建一個LINQ對象。我的理解是對象應該創建爲不可變的,除非您確實需要稍後更改這些值,所以我已經創建了私人設置器。C# - 如何創建一個LINQ到對象的不可變對象

public class GeoLookupResult 
{ 
    public string LocationType { get; private set; } 
    public string Country { get; private set; } 
    public string CountryIso3166 { get; private set; } 

    public GeoLookupResult(string locationType, string country, string countryIso3166) 
    { 
     this.LocationType = locationType; 
     this.Country = country; 
     this.CountryIso3166 = countryIso3166; 
    } 
} 

但後來似乎我不能使用LINQ到對象來創建這樣構造一個對象(因爲「GeoLookupResult不包含‘的locationType’的定義」等):

XDocument document; 

document = XDocument.Load("http://api.wunderground.com/api/d36f54198ebbb48c/geolookup/q/England/London.xml"); 

var query = from i in document.Descendants("response") 
select new GeoLookupResult 
{ 
    locationType = (string)i.Element("location").Element("type"), 
    country = (string)i.Element("location").Element("country"), 
    countryIso3166 = (string)i.Element("location").Element("country_iso3166") 
}; 

有沒有一種方法可以使用這樣的構造函數?或者我應該抓住不變性的想法,只是有公共屬性設置器並使用LINQ查詢中的那些? (EG:LocationType = (string)i.Element("location").Element("type")

回答

3

我不能完全肯定,如果我得到你的問題是正確的,但你試過這種

var query = from i in document.Descendants("response") 
       select new GeoLookupResult(
        (string)i.Element("location").Element("type"), 
        (string)i.Element("location").Element("country"), 
        (string)i.Element("country_iso3166") 
       ); 

這樣,您將有三個參數來調用你定義的GeoLookupResult類的構造函數?你現在擁有它的方式,它試圖調用默認的構造函數,然後通過他們的setter來分配你提供的屬性,你聲明爲私有。

+1

嗨,這工作表示感謝。我沒有意識到可以在查詢中使用構造器。 – user9993 2014-08-31 09:53:19

+0

如果此答案有助於解決您的問題,請考慮將其標記爲接受的答案(左側爲綠色勾號)。謝謝! – 2014-09-01 05:36:00

2

當然你可以使用你自己的構造函數。你用過的名字叫Object Initializernew GeoLookupResult{..}。當你不想用構造函數強制對象初始化時,它主要用到。

因此,您應該調用您自己的構造函數來代替Object Initializer

var query = from i in document.Descendants("response") 
select new GeoLookupResult( 
    (string)i.Element("location").Element("type"), 
    (string)i.Element("location").Element("country"), 
    (string)i.Element("country_iso3166") 
); 
2

你所提到的構造函數的不是一個面向對象的構造函數,但它是一個對象初始化機制(一個C#編譯器語法糖)有利於填充公共屬性和對象的領域。 如果你堅持讓你的對象不可變,你應該使用構造函數/工廠方法讓其他組件創建你的對象。