Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 修改IEnumerable<;T>;或ICollection<;T>;当使用泛型类型传递给类时_C#_Generics_Collections_Ienumerable - Fatal编程技术网

C# 修改IEnumerable<;T>;或ICollection<;T>;当使用泛型类型传递给类时

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

使用泛型类型时,在修改IEnumerable值时遇到了一些麻烦。
下面是一段代码:

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