7

一部の C# コードで奇妙な動作が見られましたが、説明が途方に暮れています。重要な理解が欠けている可能性があるので、誰かが私のために光のスイッチを入れてくれることを願っています.

次のようなコード ブロックがあります。

    IEnumberable<myObject> objects = GetObjectsFromApiCall();

    for (int i = 0; i < objects.Count(); i++)
        {
            if (String.IsNullOrEmpty(objects.ElementAt(i).SubObject.Title))
            {
                SubObject sub = GetSubObjectFromDatabase((long)objects.ElementAt(i).SubObject.Id);
                if (sub != null)
                {
                    objects.ElementAt(i).SubObject.Title = sub.Title;
                }
            }
        }

ステップ実行すると、このコードに関するすべてが適切に機能しているように見えます。「オブジェクト」コレクションは期待どおりに設定されています。「サブ」は収集されたものとしてフェッチされ、入力された Title プロパティを含む、期待されるプロパティの完全なセットを持ちます。実行中にエラーはスローされません。

しかし...各オブジェクトに存在する SubObject.Title プロパティ (標準の get; set; コードのみ) は頑固に空のままです。

私は途方に暮れています。何が起こっているのか説明してくれる人はいますか?

編集: for ループと ElementAt を使用しないことを提案した人のために、foreach ループから始めましたが、毎回新しいサブオブジェクトをフェッチしていたため、それが問題の原因である可能性があると考えました。あなたの助けのおかげで今修正され、ForEach が復元されました。

乾杯、マット

4

5 に答える 5

4

私はこのように修正します:

var objects = GetObjectsFromApiCall().ToList();

次に、ループをそのままにしておく(機能する)か、他の回答で示唆されているように foreach と Linq を使用して少し最適化することができますが、実際には問題ではありません。問題は、IEnumerator< の要素を変更しようとしたことです。 > @Ahmet Kakıcı が指摘したこの質問で説明されているように。

于 2013-03-08T13:02:33.393 に答える
2

これを試して

List<myObject> objects = GetObjectsFromApiCall().ToList();

foreach(var obj in objects.Where(o => string.IsNullOrEmpty(objects.SubObject.Title)).ToList())
{
    var subObject = GetSubObjectFromDatabase(obj.SubObject.Id);
    if(subObject == null) continue;

    obj.SubObject.Title = subObject.Title;
}
于 2013-03-08T13:06:06.307 に答える
1

まず第一に、ElementAt()この種のコードには使用しないでください。

foreach (var o in objects)
{
    if (string.IsNullOrEmpty(o.SubObject.Title))
    {
        o.SubObject.Title = ...;
    }
}

IEnumerableまた、メソッドが動的を返す場合、API を呼び出すたびにobjects.Something()再度呼び出され、新しいコピーが取得されることに注意してください。この場合は、.ToList()メソッドを使用して列挙型をリストにコピーする必要があります。

次のような動的列挙子を作成することにより、リストにコピーを入れない方法もあります。

objects = objects.Select(o =>
{
    if (string.IsNullOrEmpty(o.SubObject.Title))
    {
        o.SubObject.Title = ...;
    }
    return o;
});

値が正しく設定されていない場合 (以前のことが役に立たなかった場合) -プロパティthrow new Exception(value)のセッターに a を追加してみてくださいTitle- それが正しい値で呼び出されているかどうかを確認してください。

于 2013-03-08T13:01:07.457 に答える
1

関数 GetObjectsFromApiCall は次のようになります。

public IEnumberable<myObject> GetObjectsFromApiCall(){
    for(var i = 0; i < 10; i++)
    {
         yield return new myObject();
    }
}

そう言えば、objects.ElementAt(i) 関数を呼び出してオブジェクトを取得するたびに、" yield return new myObject()" によって新しいオブジェクトが取得されます。

于 2013-03-08T13:28:36.147 に答える