首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >测试泛型类型是否支持ICloneable

测试泛型类型是否支持ICloneable
EN

Stack Overflow用户
提问于 2016-06-08 04:35:35
回答 3查看 442关注 0票数 1

我有一个名为ValueFrequency的结构,它作为一个结构开始它的生命,您(出于统计原因)可以在其中存储一个(双精度)值和一个(整型)频率(告诉这个值在一组数据中出现的次数)。例如,如果你有一个值为1,1,1,2,2,3,4,4,4,4,4的列表/数组,它可以存储为ValueFrequency的列表/数组,而不是:(1,3),(2,2),(3,1),(4,5)。

无论如何,我发现我可以使用泛型来代替硬编码我的scruct来使用double,所以我可以将它与其他数据类型一起使用(例如,当使用它来存储来自二维数据集的数据时,使用它来存储数据)。

结构的简化版本:

代码语言:javascript
复制
public struct ValueFrequency<T> : IComparable, ICloneable where T : IComparable
{
  public T value;
  public int Frequency;
}

我的问题是,我想将这个结构与支持ICloneable和ValueTypes的结构/类一起使用,比如double。我如何编写一个复制构造函数(从另一个ValueFrequncy复制它的字段),它将简单地分配相同的值(如果类型是ValueType)或克隆(如果结构/类支持IClonable):

代码语言:javascript
复制
public ValueFrequency(ValueFrequency<T> valueFrequency)
{
  if (typeof(T).IsValueType)
    this.Value = valueFrequency.Value;
  else if (T is supporting IClonable)  // pseudo-code ???
    this.Value = (T)valueFrequency.Value.Clone();
  else
    throw new Exception("T must be ValueType or IClonable") ;
  this.Frequency = valueFrequency.Frequency;
}

正如您所看到的,我的问题是测试T是否为IClonable,以及实际的克隆(将T类型转换为IClonable以执行克隆)。

EN

回答 3

Stack Overflow用户

发布于 2016-06-08 04:43:13

您关心的是类型实现ICloneable,还是只关心底层对象是ICloneable

代码语言:javascript
复制
else if (valueFrequency.Value is ICloneable) 
    this.Value = (T)((ICloneable)valueFrequency.Value).Clone();
票数 3
EN

Stack Overflow用户

发布于 2016-06-08 04:42:01

您可以像这样使用IsAssignableFrom方法:

代码语言:javascript
复制
 bool is_cloneable = typeof(ICloneable).IsAssignableFrom(typeof(T));

或者,您可以将valueFrequency.Value转换为ICloneable,然后测试它是否为null,如下所示:

代码语言:javascript
复制
ICloneable value_as_cloneable = valueFrequency.Value as ICloneable;

if(value_as_cloneable != null)
    this.Value = (T)value_as_cloneable.Clone();
票数 2
EN

Stack Overflow用户

发布于 2016-06-09 14:25:56

感谢你们(Yacoub Massad和D Stanley),我最终实现了你们的两个解决方案。我决定实现我的(复制)构造函数(它实现了D Stanley的建议):

代码语言:javascript
复制
public ValueFrequency(ValueFrequency<T> valueFrequency)
{
    if (valueFrequency.Value is ICloneable)
        Value = (T)((ICloneable)valueFrequency.Value).Clone();
    else
        Value = valueFrequency.Value;
    _frequency = valueFrequency.Frequency;
}

此结构的另一个方法可以获取ValueFrequency的IEnumerable (它保存一个值(T)和一个频率(int)),并将其“解压缩”到一个值列表(T)中,其中每个值与频率一样重复多次(此方法实现了Yacoub Massad的建议):

代码语言:javascript
复制
public static List<T> ListOfValueFrequencyToList(IEnumerable<ValueFrequency<T>> valueFrequencyList)
{
    bool isCloneable = typeof(ICloneable).IsAssignableFrom(typeof(T));
    List<T> result = new List<T>();
    foreach (ValueFrequency<T> vf in valueFrequencyList)
    {
        for (int i = 0; i < vf.Frequency; i++)
        {
            if (isCloneable)
                result.Add((T)((ICloneable)vf.Value).Clone());
            else
                result.Add(vf.Value);
        }
    }
    return result;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37688854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档