web-dev-qa-db-ja.com

'object'には 'GetEnumerator'のパブリック定義が含まれていないため、Foreachステートメントはタイプ 'object'の変数を操作できません

APIを介してオブジェクトの値にアクセスする方法を理解しようとしていますが、うまくいきません。いくつかのドキュメントがありますが、多くはありません。一部の情報にアクセスできますが、探しているのは、ソフトウェアが使用しているデータベースのキーワードフィールドにあります。オブジェクトタイプを印刷することはできますが、実際のオブジェクトの値を印刷することはできません。

これが私のコードです:

 public class Test
    {
        public static ServiceConnection ConnectToDocuWare(Uri uri, string userName, string passWord)
        {
            return ServiceConnection.Create(uri, userName, passWord);
        }

        static void Main()
        {

            var userName;
            var passWord;
            var uri;
            var conn = ConnectToDocuWare(uri, userName, passWord);
            var org = conn.Organizations[0];
            var fileCabinets = org.GetFileCabinetsFromFilecabinetsRelation().FileCabinet;
            var fileCabinet = fileCabinets.SingleOrDefault(x => x.Name == "someValue");
            string documentID = "1";
            int DWID = int.Parse(documentID);
            string FCID = fileCabinet.Id;


            var dialogInfoItems = fileCabinet.GetDialogInfosFromDialogsRelation();
            var dialog = dialogInfoItems.Dialog.SingleOrDefault(x => x.DisplayName == "Some Value").GetDialogFromSelfRelation();
            var DocResults = RunQuery(dialog, documentID);


            foreach (Document doc in DocResults.Items)
            {
                var item = doc.GetDocumentFromSelfRelation();


                foreach (var itemInfo in item.Fields)
                {
                    if (itemInfo.ItemElementName.ToString() == "Keywords")
                    {
                        Console.WriteLine(itemInfo.Item);

                    }
                }
            }
        Console.ReadLine();
        }

        public static DocumentsQueryResult RunQuery(Dialog dialog, string DWDocID)
        {
            var q = new DialogExpression()
            {
                Operation = DialogExpressionOperation.And,
                Condition = new List<DialogExpressionCondition>()
                {
                    DialogExpressionCondition.Create("DWDOCID", DWDocID),
                },
                Count = 100,
                SortOrder = new List<SortedField>
                {
                    SortedField.Create("DWSTOREDATETIME", SortDirection.Desc)
                }
            };
            var queryResult = dialog.GetDocumentsResult(q);
            return queryResult;
        }
    }

これは、オブジェクトタイプを出力するだけです。 foreachループを使用してItemInfo.Itemオブジェクトのすべてを出力しようとしましたが、次のエラーが発生します。「object」には「GetEnumerator」のパブリック定義が含まれていないため、Foreachステートメントは「object」タイプの変数を操作できません。

基本的に、後で使用するためにキーワードフィールドの値にアクセスしようとしています。

4
Tom D

エラーメッセージは非常に明確です。foreachメソッドのパブリック定義を持つオブジェクトでのみGetEnumeratorループを使用できます。

foreach、in(C#Reference) Microsoftドキュメントのページから:

foreachステートメントは、 _System.Collections.IEnumerable_ または _System.Collections.Generic.IEnumerable<T>_ インターフェイスを実装する配列またはオブジェクトコレクションの各要素に対して、埋め込みステートメントのグループを繰り返します。

これは、foreachループのin部分に使用されているものはすべて列挙子を提供する必要があるため、必要なクラス(または構造体)のインスタンスでforeachループを使用できないことを意味します。

興味深い事実: Enigmativity で指摘されているように この回答 、foreachループが機能するために本当に必要なのは、GetEnumerator()と呼ばれるパブリックメソッドを持つことだけです。パブリックメソッドが、いくつかのメソッドとプロパティ、つまりvoid Reset()bool MoveNext()、および_T Current { get; private set; }_を持つインスタンスを返すようにします。ここで、Tはあるタイプです。

これは、クラスをIEnumerableまたは_IEnumerable<T>_インターフェースを実装するものとして宣言する必要がなく、列挙子がIEnumeratorまたは_IEnumerator<T>_インターフェースを実装するものとして宣言する必要がないことを意味します-提供するだけで十分ですメソッドとプロパティは、関連するインターフェイスを定義しました-これが、c#コンパイラがforeachループを使用するために要求するすべてです。

5
Zohar Peled