当 HashSet<T> 作为对象提供并且 T 可以是任何东西时,如何遍历它?



我使用值注入器从一个类型映射到另一个使用LoopValueInjection和覆盖SetValue(对象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);
    }

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

在。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) });
}

使用说明:

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,那么您可以枚举和添加,否则只能枚举。

相关内容

  • 没有找到相关文章

最新更新