我真的不知道如何在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属性)。
你的问题是你的泛型参数被错误地指定了。
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>();
}