C# 如何循环通过哈希集<;T>;当它作为对象提供时,T可以是任何东西?

C# 如何循环通过哈希集<;T>;当它作为对象提供时,T可以是任何东西?,c#,reflection,valueinjecter,C#,Reflection,Valueinjecter,我使用值注入程序使用LoopValueInjection从一种类型映射到另一种类型,并使用一些自定义逻辑重写SetValue(object v)方法。我试图检测何时传入一个HashSet,并遍历该HashSet,对其中的每个项应用一个方法来进行清理。我遇到的问题是,参数只是一个对象,我不知道散列集中的项的类型。例如,它可以是HashSet或HashSet 这是我目前拥有的代码,但我得到了一个InvalidCastException protected override object Se

我使用值注入程序使用LoopValueInjection从一种类型映射到另一种类型,并使用一些自定义逻辑重写SetValue(object v)方法。我试图检测何时传入一个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);
    }
受保护的覆盖对象设置值(对象v)
{
if(type.Name==“HashSet`1”)
{
var genericType=type.GetGenericArguments()[0];
//此行抛出InvalidCastException
var cleanhasset=(HashSet)Activator.CreateInstance(类型);
foreach(var item in(HashSet)v)//我确信这个cast也会抛出
{
添加(Clean(item));
}
返回cleanhasset;
}
返回基本设置值(v);
}

我想主要的问题是,一旦我确定HashSet实际上是某种HashSet,如何循环作为对象传入的HashSet?我还认为我还需要创建一个新的特定类型的空哈希集,这样我就可以将每个被清理的项放入其中。

在.NET中,只有接口和委托类型可以是共变和逆变的。因此,无法将
HashSet
强制转换为
HashSet

您想将
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) });
}
使用:

bool-isHashSet=typeof(HashSet).IsAssignableFrom(type);

对象x=。。。 HashSet hs=x作为HashSet; 如果(hs!=null) { //使用hs } 如果确实指定了
,请使用它而不是
对象



HashSet
ICollection
IEnumerabel
IEnumerable
。如果您知道
T
,则可以枚举和添加。否则只枚举。

@hazzik:谢谢。固定的。尽可能多。这正是我需要的,没有考虑动态。谢谢
bool isHashSet = typeof(HashSet<object>).IsAssignableFrom(type);
object x = ...
HashSet<object> hs = x as HashSet<object>;
if (hs != null)
{
    // use hs
}