C# 修改IEnumerable<;T>;或ICollection<;T>;当使用泛型类型传递给类时
使用泛型类型时,在修改IEnumerable值时遇到了一些麻烦。C# 修改IEnumerable<;T>;或ICollection<;T>;当使用泛型类型传递给类时,c#,generics,collections,ienumerable,C#,Generics,Collections,Ienumerable,使用泛型类型时,在修改IEnumerable值时遇到了一些麻烦。 下面是一段代码: public class ParameterArray<TEnumerable, TType> : IParameterArray<TEnumerable, TType> where TEnumerable : ICollection<TType> // Note that I have tried with IEnumerable<TType> i
下面是一段代码:
public class ParameterArray<TEnumerable, TType> : IParameterArray<TEnumerable, TType>
where TEnumerable : ICollection<TType> // Note that I have tried with IEnumerable<TType> instead of ICollection<TType>, but did not really help
{
public ParameterArray(TEnumerable value, TType minValue, TType maxValue)
{
MinValue = minValue;
MaxValue = maxValue;
Value = value;
}
private TEnumerable _value;
public TEnumerable Value
{
get => _value;
set
{
ICollection<TType> checkedValue;
// Here I want to check the range before setting the value
// Note that Value can be of type int[], float[], bool[], byte[]
// I have tried many work around, but for some reasons, I am never able to update _value
for (int idx = 0; idx < value.Count(); idx++)
{
// Backup value after range limiting
checkedValue.Add(CheckRange(value.ElementAt(idx)));
}
// Would like to save these new values in _value, but not sure how to
_value = checkedValue as TEnumerable; // Or (TEnumerable)checkedValue; // !!! Breaking here at runtime - Cannot convert from one type to the other
}
}
public TType CheckRange(TType value)
{
TType retValue = value;
if (value != null)
{
// Restrict range to Min/Max
if (Comparer<TType>.Default.Compare(MaxValue, value) < 0)
retValue = MaxValue;
else if (Comparer<TType>.Default.Compare(MinValue, value) > 0)
retValue = MinValue;
}
else
{
throw new ArgumentOutOfRangeException($"Value cannot be null: Range is {MinValue} to {MaxValue}");
}
return retValue;
}
}
公共类参数数组:IParameterArray
where TEnumerable:ICollection//注意,我尝试过使用IEnumerable而不是ICollection,但没有真正起到帮助
{
公共参数数组(TEnumerable value、TType minValue、TType maxValue)
{
MinValue=MinValue;
MaxValue=MaxValue;
价值=价值;
}
私有可数(u)值;;
公共可数价值
{
获取=>\u值;
设置
{
i采集校验值;
//在这里,我想在设置值之前检查范围
//请注意,值的类型可以是int[],float[],bool[],byte[]
//我尝试了很多方法,但由于某些原因,我无法更新_值
for(int idx=0;idx0)
retValue=MinValue;
}
其他的
{
抛出新ArgumentOutOfRangeException($”值不能为null:范围为{MinValue}到{MaxValue}”);
}
返回值;
}
}
不知何故,我无法将我的ICollection备份到我的_值(这是一个可数的值)。然而,考虑到我已经声明TEnumerable是从ICollection派生出来的(即,where-TEnumerable:ICollection),我不太明白其中的原因
我尝试过多种方法,但它们都会导致无法将结果分配给_值的相同问题
欢迎提出任何建议。也许我需要的不是:where TEnumerable:I集合 编辑和解决方案 正如@nvoigt所建议的,我已经重新格式化了我的类,这样它就不会接受一个TEnumerable作为输入。这个额外的抽象层产生了额外的复杂性,使得一切都难以处理。
以下是最终的解决方案:
public class ParameterArray<TType> : ParameterBase, IParameterArray<TType>
{
public ParameterArray(IEnumerable<TType> value, TType minValue, TType maxValue)
{
MinValue = minValue;
MaxValue = maxValue;
Value = value;
}
private IEnumerable<TType> _value;
public IEnumerable<TType> Value
{
get => _value;
set
{
IList<TType> checkedValue = new List<TType>();
for (int idx = 0; idx < value.Count(); idx++)
{
// Range limiting
checkedValue.Add(CheckRange(value.ElementAt(idx)));
}
// Back up the updated value
_value = checkedValue.ToArray();
}
}
public TType CheckRange(TType value)
{
// Unchanged
...
}
}
公共类ParameterArray:ParameterBase、iPareterArray
{
公共参数数组(IEnumerable值、TType minValue、TType maxValue)
{
MinValue=MinValue;
MaxValue=MaxValue;
价值=价值;
}
私有IEnumerable_值;
公共可数价值
{
获取=>\u值;
设置
{
IList checkedValue=新列表();
for(int idx=0;idx
让我看看。假设我将TEnumerable
设为int[]
并且ckeckedValue
设为ICollection
则编译器是正确的。。。不能使用as
运算符从相同基类型的ICollection
创建数组。不管是泛型还是非泛型,这都不起作用
我真的不能提出一个好的方法。如果是我,我会放弃通用的可枚举部分,将其变成
列表
或数组
,然后使用它。如果您有明确的约束要求该零件为通用零件,您可能应该将其与问题一起发布,以便我们可以根据这些约束建议不同的解决方案。ICollection ckeckedValue=default代码>。。。没有道理。。。它是null
(和ckeckedValue.Add(…)
将导致NPE)。。。另外,定义“不工作”提示…只需将\u值
a列表
…编辑后:您可以明显地将setter缩短为\u值=新列表(值。选择(检查范围))代码>..@Selvin,没有_值应该是Arraysee…:)谢谢你的意见。那么您不会将该类声明为ParameterArray吗?不,我会将其声明为ParameterArray
,它在构造函数中接受IEnumerable
和最小值和最大值,并构建自己的列表。我的意思是,在您第一次调用add之后,您还是可以从一开始就创建副本。这样我就可以用这种方式实例化这个类了?新ParameterArrayNot,它允许您这样使用:newParameterArray(new[]{1,2,3},1,9)代码>它似乎确实有效。再次感谢你的建议。按照你的建议重新定义我的班级是一条路。我已经为这些泛型类型挣扎了很长一段时间了,希望我以前有你的意见。你一次解决了两个问题!非常感谢!
ckeckedValue as TEnumerable