1

私の質問の重点は、C# Genericsと、インターフェイスIXListまたはIYListをこの「GetAllValues ()」メソッドに渡すことです。目標は、GetAllValues<IXList>()-Or-を呼び出すための共通コードですGetAllValues<IYList>()

09-21-13 フォローアップ: 私は次のことを学びました: where Z : IXList, IYListZ が型であることを意味しIXListITList- この理解があれば試してみるかもしれませんwhere Z : classが、これはせいぜいまだ機能しない横方向のステップであり、Z.anything...anythingが見つからないため、コンパイラはZ...について無知です

渡された Z の実際の型をテストしてから、条件付き実行時コードで正しいキャストlistを選択して、それに応じて .Head()、.Get()、および .Next() を呼び出すことはできますか? 例: ((IXList)list).Head(); -または- ((IYList)list).Head(); [[ はい、可能です。2013 年 9 月 24 日のコードの下にある 2 番目の回答を参照してください。]]

09-29-13 フォローアップ: そして最後に、以下に投稿された回答/解決策#3は、最終的な解決策をよりオブジェクト指向のものに移行します。したがって、この 3 番目の解決策、ジェネリックの型を尋ねる方法と、最初に発生したコンパイラのあいまいなエラーを解決する方法に関する私の最初の質問を意味のないものにします。[[09-29-13 日付の下のコードで、回答/解決策 #3 を参照してください。]]

    internal static IEnumerable<int> GetAllValues<Z>(Z list)
        where Z : IXList, IYList
    {
        try
        {
            list.Head();        // Error 344 - The call is ambiguous between the following
                                // methods or properties: 'IXList.Head()' and 'IYList.Head()'   
        }
        catch (Exception)
        {
            yield break;
        }

        do
        {
            IntPtr lineItemPointer;
            int x = list.Get();     // Error 345 - The call is ambiguous between the following
                                    // methods or properties: 'IXList.Get()' and 'IYList.Get()' 

            yield return x;

            try
            {
                list.Next();        // Error 346 -The call is ambiguous between the following
                                    // methods or properties: 'IXList.Next()' and 'IYList.Next()'   
            }
            catch (Exception)
            {
                yield break;
            }
        } while (true);
    } 
4

3 に答える 3

0

以下は、IXList または IYList のいずれかを処理するロジックの共通コードという、私が求めていた目標を正確に達成します。うん!

そして、拡張メソッドとして、ユーザーは必要な「GetAllItems」タイプのバージョンを取得します...

var landRecs = _land.MainXList().GetAllItems();

var landAltRecs = _land.AlternateYList().GetAllItems();

    internal static IEnumerable<Iint> GetAllItems(this IXList list)
    {
        return GetAllItemsGeneric<Iint, IXList>(list);
    }

    internal static IEnumerable<string> GetAllItems(this IYList list)
    {
        return GetAllItemsGeneric<string, IYList>(list);
    }                                                                                                                                   

    private static IEnumerable<Zout> GetAllItemsGeneric<Zout, T>(T list)
        where Zout : class      // (string -or- int)  -or-  (IReadOnlyTxnMisc or ITxnMisc) etc.
        where T : class         // IYList  -or- IXList  
    {
        try
        {
            DoHeadforList<T>(list);
        }
        catch (Exception)
        {
            yield break;
        }

        Guid guid = Marshal.GenerateGuidForType(typeof(Zout));

        do
        {
            Zout rec = null;
            try
            {
                IntPtr itemPointer;
                itemPointer = DoGetItemforList<T>(list, ref guid);
                rec = Marshal.GetObjectForIUnknown(itemPointer) as Zout;
            }
            catch (Exception)
            {
                yield break;
            }

            if (rec != null)
            {
                yield return rec;
            }
            else
            {
                yield break;
            }

            try
            {
                DoNextforList<T>(list);
            }
            catch (Exception)
            {
                yield break;
            }
        } while (true);
    }

    private enum IListType
    {
        X,
        Y,
        Unknown
    }

    private static IListType GetListTypeAsEnum<T>() where T : class
    {
        IListType rtType = IListType.Unknown;      
        Type inListType = typeof(T);

        if (inListType == typeof(IXList))
        {
            rtType = IListType.X;
        }
        else if (inListType == typeof(IYList))
        {
            rtType = IListType.Y;
        }
        return rtType;
    }

    private static IntPtr DoGetItemforList<T>(T list, ref Guid guid) where T : class
    {
        IntPtr itemPointer;
        if (list == null)
        {
            throw new ArgumentNullException("end of list");
        }
        switch (GetListTypeAsEnum<T>())
        {
            case IListType.X:
                ((IXList)list).GetItem(ref guid, out itemPointer);
                break;
            case IListType.Y:
                ((IYList)list).GetItem(ref guid, out itemPointer);
                break;
            default:
                throw new ArgumentException("unknown passed type");
        }
        return itemPointer;
    }

    private static void DoHeadforList<T>(T list) where T : class
    {
        if (list == null)
        {
            throw new ArgumentNullException("end of list");
        }
        switch (GetListTypeAsEnum<T>())
        {
            case IListType.X:
                ((IXList)list).Head();
                break;
            case IListType.Y:
                ((IYList)list).Head();
                break;
            default:
                throw new ArgumentException("unknown passed type");
        }
    }

    private static void DoNextforList<T>(T list) where T : class
    {
        if (list == null)
        {
            throw new ArgumentNullException("end of list");
        }
        switch (GetListTypeAsEnum<T>())
        {
            case IListType.X:
                ((IXList)list).Next();
                break;
            case IListType.Y:
                ((IYList)list).Next();
                break;
            default:
                throw new ArgumentException("unknown passed type");
        }
    }
于 2013-09-24T16:39:26.753 に答える