2

メソッドに次の辞書があります。

var nmDict = xelem.Descendants(plantNS + "Month").ToDictionary(
    k => new Tuple<int, int, string>(int.Parse(k.Ancestors(plantNS + "Year").First().Attribute("Year").Value), Int32.Parse(k.Attribute("Month1").Value), k.Ancestors(plantNS + "Report").First().Attribute("Location").Value.ToString()),
    v => { 
             var detail = v.Descendants(plantNS + "Details").First();                
             return
                 new
                    {
                      BaseHours = detail.Attribute("BaseHours").Value,
                      OvertimeHours = detail.Attribute("OvertimeHours").Value
                    };
         });

nmDictを返す必要があります。問題は、メソッドシグネチャにラベルを付ける方法がわからないことです。私は以下を試しました:

protected IDictionary<XElement, XElement> OvertimereportData(HarvestTargetTimeRangeUTC ranges)

上記は私にこのエラーを与えます:

Cannot implicitly convert type System.Collections.Generic.Dictionary<System.Tuple<int,int,string>,AnonymousType#1>' to 'System.Collections.Generic.IDictionary<System.Xml.Linq.XElement,System.Xml.Linq.XElement>'. An explicit conversion exists (are you missing a cast?) 


protected IDictionary<Tuple, XElement> OvertimereportData(HarvestTargetTimeRangeUTC ranges)

私にこのエラーを与えます:

'System.Tuple': static types cannot be used as type arguments   

私は何をすべきかわかりません。

4

3 に答える 3

3

簡単な答え:関数から匿名型を返すことはできません。

長い答え:あなたの辞書の値型は匿名{BaseHours, OvertimeHours}であり、関数から返すことも引数として渡すこともできません(オブジェクトとしての場合を除きますが、それを反映する手間をかけない限り、それは何の役にも立ちません)。クラス/構造体をその中に定義するかBaseHoursOvertimeHoursタプルを使用します。BaseHours名前とOvertimeHours;を保持できるため、前者の方がおそらく少し優れています。タプルを使用すると、取得するだけValue1ですValue2

于 2012-08-14T18:24:30.650 に答える
2

C#4.0を使用している場合は、動的タイプを介して匿名を返すことができます。したがって、メソッドシグネチャは次のようになります

protected IDictionary<Tuple<int,int,string>, dynamic> OvertimereportData(HarvestTargetTimeRangeUTC ranges)

また、動的オブジェクトを介して、実行時にプロパティを見つけることができます。

これがお役に立てば幸いです。

于 2012-08-14T18:34:20.263 に答える
1

メソッドを呼び出すとToDictionary、結果のディクショナリのタイプは、ソースシーケンスの要素のタイプとはほとんど関係がありません。これは、呼び出しに指定するキー式と値式によって返されるデータ型によって完全に定義されます。たとえば、次のように電話する場合:

xelem.Descendants(plantNS + "Month").ToDictionary(
  k => int.Parse(k.Attribute("Year").Value),
  v => k.Attribute("Year).Value
);

それがIDictionary<int, string>あなたの2つの式が返したものだからです。メソッドからそれを返すには、式に基づいて正しい型を作成する必要があります。

あなたの最初のものは簡単です:

k => new Tuple<int, int, string>(...)

ただし、2つ目は問題になります。ディクショナリの値は匿名タイプですnew { }。その値の具体的なタイプ名を指定せずにを返します。一般に、それはあなたがその辞書を戻り値またはパラメータとして使用することを不可能にするでしょう。(非常に奇妙に見える一般的な手法を使用して実行できますが、お勧めしません。)

次に、最初に行う必要があるのは、値を保持するための具体的な型を作成することです。

public class HoursContainer 
{
  public string BaseHours { get; set; }
  public string OvertimeHouse { get; set; }
}

Linqクエリを適切に変更します。

var detail = v.Descendants(plantNS + "Details").First();                
return new HoursContainer
{
    BaseHours = detail.Attribute("BaseHours").Value,
    OvertimeHours = detail.Attribute("OvertimeHours").Value
};

これを行うと、辞書は、作成時に指定したもののタイプに基づいた具体的なタイプになります。

IDictionary<Tuple<int, int, string>, HoursContainer>

(注:Tuple<int, int>必要に応じて、ここで別のタイプを使用することもできますが、結果の汎用タイプは非常に速く扱いにくくなります。)

于 2012-08-14T18:29:12.043 に答える