3

LoopValueInjection を使用し、いくつかのカスタム ロジックで SetValue(object v) メソッドをオーバーライドして、ある型から別の型にマップするために Value Injecters を使用しています。HashSet が渡されたときを検出し、HashSet を通過し、その中の各項目にメソッドを適用してクリーンアップを実行しようとしています。私が抱えている問題は、パラメーターが単なるオブジェクトであり、HashSet 内のアイテムのタイプがわからないためです。たとえば、HashSet または HashSet などです。

ここに私が現在持っているコードがありますが、InvalidCastException が発生しています。

    protected override object SetValue(object v)
    {
        if (type.Name == "HashSet`1")
        {
            var genericType = type.GetGenericArguments()[0];

            // this line throws the InvalidCastException 
            var cleanHashSet = (HashSet<object>)Activator.CreateInstance(type);

            foreach (var item in (HashSet<object>)v)  // I'm sure this cast will throw as well
            {
                cleanHashSet.Add(Clean(item));
            }

            return cleanHashSet;
        }

        return base.SetValue(v);
    }

主な問題は、実際に何らかの種類の HashSet であると判断した後、オブジェクトとして渡された HashSet をどのようにループ処理できるかということだと思います。また、特定のタイプの新しい空の HashSet も作成する必要があると考えています。これにより、クリーンアップされる各アイテムをその中に入れることができます。

4

2 に答える 2

8

.NET では、インターフェイスとデリゲート型のみが共変および反変になります。したがって、にキャストHashSet<SomeType>することはできませんHashSet<object>

インターフェイスvの非ジェネリック バージョンにキャストしたいIEnumerable

dynamic cleanHashSet = Activator.CreateInstance(type);
foreach (object item in (IEnumerable)v)
{
    cleanHashSet.Add(Clean(item)); 
}

キーワードを使用したくない場合は、リフレクションでメソッドdynamicを呼び出す必要がありますAdd

object cleanHashSet = Activator.CreateInstance(type);
var method = type.GetMethod("Add");
foreach (object item in (IEnumerable)v)
{
    method.Invoke(cleanHashSet, new object[] { Clean(item) });
}
于 2013-03-19T04:15:06.550 に答える
0

使用する:

bool isHashSet = typeof(HashSet<object>).IsAssignableFrom(type);

また

object x = ...
HashSet<object> hs = x as HashSet<object>;
if (hs != null)
{
    // use hs
}

本当に<T>指定した場合は、代わりに使用してくださいobject


HashSet<T> ICollection<T>IEnumerabel<T>、 を実装IEnumerableします。T列挙と追加の両方ができることを知っているとはどういう意味ですか。それ以外の場合は、列挙のみを列挙します。

于 2013-03-19T04:16:21.073 に答える