在 foreach 循环中使用通用类型

问题描述 投票:0回答:1

我真的不知道如何在IEnumerable中使用泛型,以便我可以通过给定的泛型值所包含的值进行迭代。

考虑下面的类(注意这里的类只是为了举例)。

public class Parameter<T> : IParameter<T> where T : IEnumerable<T>
{
  public List<UInt64> output = new List<UInt64>();

   private T _value;
   public T Value
   {
       get => ...;
       set
       {

           // I want to be able to apply special treat to the value
           // Value can be of any type: int, int[], bool, bool[]
           foreach (var v in value)
           {
               output.Add(Convert.UInt64(v) + 5);
           }

           ...

       }
   }
}

public interface IParameter<T> where T : IEnumerable<T>
{
   T Value { get; set; }
}

我有一个测试模块,它可以按要求实例化一些参数,但我甚至不能在这里编译。我甚至尝试在下面这里把bool[]替换成IEnumerable,但是编译器也不喜欢。

public class TestModule : ModuleBase, ITestModule
{
    public IParameter<bool[]> Test1 { get; set; } = new Parameter<bool[]>();
    public IParameter<uint[]> Test2 { get; set; } = new Parameter<uint[]>();
    ...
    public IParameter<int> Test3 { get; set; } = new Parameter<int>();
}

我确实考虑过为Parameter()类使用overload,但我认为为每个支持的类型创建一个类是矫枉过正的(考虑到它只针对Value属性)。

c# generics ienumerable
1个回答
1
投票

你的问题是你的泛型参数被错误地指定了。

public class Parameter<T> : IParameter<T> where T : IEnumerable<T>

意味着不管是什么类型的T,都是同一类型的可枚举的,比如说一个类型的T bool[] 应是 IEnumerable<bool[]> 这显然是不正确的。

让它编译的一个方法是这样的。

    public class Parameter<TEnumerable, TType> : IParameter<TEnumerable, TType> where TEnumerable : IEnumerable<TType>
    {
        public List<ulong> output = new List<ulong>();

        private TEnumerable _value;
        public TEnumerable Value
        {
            get => { return null; }
            set
            {

                // I want to be able to apply special treat to the value
                // Value can be of any type: int, int[], bool, bool[]
                foreach (Q v in value)
                {
                    output.Add(Convert.ToUInt64(v) + 5);
                }
            }
        }
    }

    public interface IParameter<TEnumerable, TType> where TEnumerable : IEnumerable<TType>
    {
        TEnumerable Value { get; set; }
    }

    public class TestModule
    {
        public IParameter<bool[], bool> Test1 { get; set; } = new Parameter<bool[], bool>();
        public IParameter<uint[], uint> Test2 { get; set; } = new Parameter<uint[], uint>();
        public IParameter<int[], int> Test3 { get; set; } = new Parameter<int[], int>();
    }

至于你的补充评论,不,你无法避免指定两种类型,因为IEnumerable不是一个T,在你编写代码的形式中。你在这里有2个独立的参数,因此,如果你必须按照你的方式来做,你将不得不使用2个通用参数。

一个更简单的解决方案是像这样的东西,它或多或少有相同的目的,尽管我并不真正了解你的要求,所以这可能会或可能不会满足(为了清楚起见,省略了接口)。

    public class Parameter<TType>
    {
        public List<ulong> output = new List<ulong>();

        private IEnumerable<TType> _value;
        public IEnumerable<TType> Value
        {
            get => { return null; }
            set
            {

                // I want to be able to apply special treat to the value
                // Value can be of any type: int, int[], bool, bool[]
                foreach (TType v in value)
                {
                    output.Add(Convert.ToUInt64(v) + 5);
                }
            }
        }
    }

    public class TestModule
    {
        public Parameter<bool> Test1 { get; set; } = new Parameter<bool>();
        public Parameter<uint> Test2 { get; set; } = new Parameter<uint>();
        public Parameter<int> Test3 { get; set; } = new Parameter<int>();
    }
© www.soinside.com 2019 - 2024. All rights reserved.