2

APIのジェネリック拡張メソッドを作成するときに、コレクションの戻りタイプを選択するというジレンマに陥っています。どのコレクションタイプを返すか、そしてデザインの選択はどうあるべきかについてのSOに関する議論を読みました。私は通常、最も基本的な型を引数として受け入れ、最も豊富な型を返すことを好みます。

私は今、提供されているのと同じタイプを返すことを考えています。これが良い選択であるかどうかに関係なく、これを使いやすい方法で達成できる方法はありますか?

たとえば。私はこれを持ってみましょう:

 public static IEnumerable<T> Generize<T>(this IEnumerable<T> source)
                                         where T : new()
 {
     var lst = source.ToList();
     lst.Add(new T());
     return lst.AsEnumerable(); //since return type is IEnumerable.
 }

ここで、引数に応じてIEnumerableICollectionまたはを返します。だから私はこれを少し修正しました。IListsource

 public static S Generize<S, T>(this S source) where S : IEnumerable<T>
                                               where T : new()
 {
     var lst = source.ToList();
     lst.Add(new T());
     return (S)lst.AsEnumerable(); //not sure if this works
 }

私が直面している主な問題は、関数を呼び出せないことですGenerize

var d = new List<int> { 23, 23 };

d.Generize(); //can not find definition and no extension method by the name.....

d.Generize<List<int>, int>(); //works but so ugly..
  1. マークが指摘しているように、キャスティングはどこでも機能するわけではありません。とにかくifSからタイプのコレクションを返すより良い方法はありますか?List<T>SIEnumerable<T>

  2. タイプが自動的に推測されるように、タイプを指定せずに実行できますか?

  3. また、なぜエラーではなくエラーd.Generize()を出すのですか?definition not foundtypes cannot be inferred

編集:

どんな具体的なタイプでもかまいませんIEnumberable<T>が、私の場合、それはnamsespaceのようなT[]、またはList<T>それ以上のものだけが通常見られるものでした。Linqそれらすべてを処理するのは簡単ではありません。元の質問が今は意味をなさないことを指摘するだけです。皆さんありがとう..!

4

1 に答える 1

0

警告:わかりました。私の質問はあまり良くありませんでした。私の考えは少しばかげています。これは私の投稿に答えるためだけのものであり、お勧めしません。List<T>私は本番コードで適切なものを返すことに依存します。

1つの方法は、いくつかの既知のタイプのコレクションクラスを処理することです。

public static S Generize<S, T>(this S source, T dummyVariable) 
                              where S : class, IEnumerable<T>
{
    var lst = source.ToList();
    lst.Add(dummyVariable);

    if (source is T[])
        return lst.ToArray() as S;

    if (source is List<T>)
        return lst as S;

    if (source is Collection<T>)
        return new Collection<T>(lst) as S;

    throw new TypeAccessException();
}

もう少し一般的に、私はいくつかの反射を使用します。

public static S Generize<S, T>(this S source, T dummyVariable) 
                              where S : class, IEnumerable<T>
{
    var lst = source.ToList();
    lst.Add(dummyVariable);

    if (source is Array)
        return lst.ToArray() as S;

    foreach (var c in typeof(S).GetConstructors())
    {
        var p = c.GetParameters();

        if (p.Length != 1)
            continue;

        if (typeof(IEnumerable<T>).IsAssignableFrom(p[0].ParameterType))
            return Activator.CreateInstance(typeof(S), lst) as S;
    }

    throw new TypeAccessException();
}

質問2はここで回答されており、質問3は謎のままです。

于 2012-11-13T20:15:56.530 に答える