2011-01-11 6 views
0

私はlinqの新しいブランドです。私は経験不足のため何かが欠けていると確信しています。Linqオブジェクト列挙型

問題:私は、私はエラーunable to cast object of type System.Collections.Generic.KeyValuePair '2[Acct]' to type 'Acct'を取得した結果を列挙しようとした場合 私はオブジェクトを照会し、列挙アカウンティングを返すためにLINQを使用していますがwhere o.Diff!=0

オブジェクト。

質問: Linqクエリから列挙可能なAcctオブジェクトを返すにはどうすればよいですか?

ありがとうございます!

public class AcctSum 
{ 
    string ID; 
    Decimal Amt1; 
    Decimal Amt2; 
    Decimal Diff; 
    ArrayList<AcctDet> lines; 
} 

public class AcctInfo 
{ 
    Dictionary<string,AcctSum> acct 

    //code that adds the data... 
    public iEnumerable Discrepancies() 
    { 
    var results = (from Acct a in acct 
        where a.Diff != 0 
        select a).AsEnumerable<Acct>(); 
    foreach (var result in results)//at runtime this generates an error 

    { 
    }          
    return results.GetEnumerator(); 
    } 
} 
+0

あなたはAcctとAcctSumを相互交換的に使用しています。それは正しいとは思わない。 Acctが列挙型の場合は、別のものに変換することはできません。 – Schultz9999

+0

'' from 'の 'Acct'を' variable1'のような型名でない変数名に変更し、 'AsEnumerable ()'を 'AsEnumerable ()'に変更し、最後に 'in acct'を' in acct.Values' –

答えて

0

あなたが繰り返し処理を行うことにしたいように聞こえる、と述べていますキーと値のペアではなく、値です。

var results = from acctSum value in acct.Values 
       where acctSum.Diff != 0 
       select acctSum; 

が、個人的に、私はこのケースでは、クエリ式を使用して気にしないでしょう。あなたはこのようなクエリを使用できることを意味

。私は、拡張メソッドを使用したい:

var results = acct.Values.Where(acctSum => acctSum.Diff != 0); 

さて、戻り値の型の面で、私は強くあなたがIEnumerable<AcctSum>はなくIEnumeratorまたはIEnumerator<T>を返すようにしたいと思います。 (むしろいい加減に巡回できないのクエリを返すよりも)一度にすべて結果を取得し、それらを返す -

public IEnumerable<AcctSum> Discrepancies() 
{ 
    return acct.Values.Where(acctSum => acctSum.Diff != 0); 
} 

をしたり、クエリが「実体化」することがあります。だから、お勧めします。 、彼らは生のクエリを反復処理している間にそうしようとした場合 - 特に

public IEnumerable<AcctSum> Discrepancies() 
{ 
    return acct.Values.Where(acctSum => acctSum.Diff != 0).ToList(); 
} 

、あなたは彼らがこれらの結果を反復処理している間に発信者がacctを変更できるようにしているクエリを実体化することにより例えば:彼らは例外を得るでしょう。

ArrayListは.NETのジェネリック型ではないため、AcctSumクラスも変更する必要があります。 List<T>を使用しましたか?

+0

ArrayListをListに切り替え、別のサンプルで見ました。私は今これを試しています、ありがとう! – kes

+0

最後の例の.ToList()は、まさに私が探していたものでした。 全体のことはまだ魔法のように感じます。 私はそれが盲目を取って新しいパラダイムを学ぶ時だと思います:) – kes

0

まあ、それはB/Cのacctのだボンネットの下に、IIRC、IEnumerableを<KeyValuePair>である(辞書です。あなたはacctを反復するとacct.Values

1

にACCTからソースを変更。各項目は、各ペアの値がAcctオブジェクトをされたと仮定すると、あなたはこのようにゼロ以外のアカウントのすべてになるだろう辞書からキー/値のペアです:

from a in acct.Values 
where a.Diff != 0 
select a 
3

の問題は、あなたも実際には、辞書の各項目がKeyValuePairである場合、各項目をAcctとしてキャストしています。

from KeyValuePair<string,AcctSum> acctKVP in acct // assuming acct is of type Dictionary<string,AcctSum> 
where acctKvp.Value.Diff != 0 
0

最初に、戻り値の型はIEnumeratorでなくIEnumerableである必要があります。他の人のよう 第二に、ACCTは、キーと値のペアのコレクションが含まれているので、あなたは(この場合は)キーの値にクエリを実行する必要が

void Main() 
{ 
    var acctInfo = new AcctInfo(); 
    acctInfo.Discrepancies(); 

} 
public class AcctSum 
{ 

    string ID; 
    Decimal Amt1; 
    Decimal Amt2; 
    public Decimal Diff; 
    ArrayList lines; 
} 

public class AcctInfo 
{ 
    public IEnumerator Discrepancies() 
    { 
     var acct = new Dictionary<int, AcctSum> 
         {{1, new AcctSum() {Diff = 0.0M}}, {2, new AcctSum() {Diff = 1.0M}}}; 

     var results = (from AcctSum a in acct.Values where a.Diff != 0 select a).AsEnumerable(); 

     foreach (var result in results)//at runtime this generates an error 
     { 

     } 
     return results.GetEnumerator(); 
    } 
} 
+0

実際には、私は 'IEnumerator'の代わりに' IEnumerable 'を返します。 IEnumerableまたはIEnumerable を実装するGetEnumeratorメソッド以外のものからイテレータを返すのは非常にまれです。 –

+0

私はそうですが、GetEnumerator()を返すとき、私はそれが意図的であると考えました。いずれにせよ、何かが変わっていた。 – Rob

+0

うん、私はうんざりした。私はforeachをやることができ、かつ/またはDataGridバインディングのために返すように実装しようとしていました。はい、バインディングのためにプロパティに変数を調整する必要がありました:) – kes