【问题标题】:How to copy between generic declared types with value type constraints如何在具有值类型约束的泛型声明类型之间进行复制
【发布时间】:2009-02-26 23:09:04
【问题描述】:

我有一个在值类型之间复制值的通用方法。即使使用结构约束,以下方法也会产生设计时错误。知道如何在值之间复制或转换吗?

private Ttgt MyMethod<Tsrc,Ttgt>(Tsrc SourceObject) 
    where Tsrc : struct
    where Ttgt : struct
{
    //Error:cannot implictly convert type 'Tsrc' to 'Ttgt'
    Ttgt returnObject = SourceObject; 

    //Error:Cannot convert type 'Tsrc' to 'Ttgt'
    Ttgt returnObject = (Ttgt)SourceObject; 

    return returnObject;
}

【问题讨论】:

    标签: c# .net generics casting generic-constraints


    【解决方案1】:

    鉴于有一个已注册的类型转换器,用于您尝试在一些反射魔法之间转换的类型可以做到这一点:

    private Ttgt MyMethod<Tsrc,Ttgt>(Tsrc sourceObject) 
        where Tsrc:struct where  Ttgt:struct    
    {    
        Type targetType = typeof(Ttgt);
        TypeConverter tc = TypeDescriptor.GetConverter(targetType);
        Ttgt returnObject = (Ttgt)tc.ConvertTo(sourceObject, targetType);
        return returnObject;    
    }
    

    但是开箱即用它的用途非常有限,因为例如 bool 和 int 之间没有转换器。你想解决什么问题?

    我还发现了另一个question,其中包含一些疯狂的转换代码。

    编辑: 您的评论清楚地表明您正在尝试在域对象和某种视图/合同模型之间执行对象到对象的映射。你看过AutoMapper吗?

    【讨论】:

    • 我正在编写一个递归对象到对象映射器。将合同类与 WCF 实现中的底层业务逻辑类分开。实现类与合同几乎相同,但我不想在两者之间引入依赖关系。
    • 这应该说:Type targetType = typeof(Ttgt);
    【解决方案2】:

    //错误:无法将类型'Tsrc'转换为'Ttgt'

    您不能在任意类型之间进行转换,除非有可访问的转换运算符。

    【讨论】:

      【解决方案3】:

      两者被定义为不同的类型。尽管它们都是结构体,但它们的类型不同。

      将源和目标定义为同一类型:

      private T MyMethod<T>(T source, T target)
      {
      

      【讨论】:

        【解决方案4】:

        这是“按设计”。您正在尝试在两个不相关的值类型之间进行转换。这永远不会成功,因此它被标记为错误。

        这对于所有值类型都是正确的,因为它们是隐式密封的。为了使 TSrc -> Ttgt 之间的转换成功,这两种类型之间必须存在类层次关系。这不可能是因为所有值类型都是密封的,因此无法从另一个派生。

        唯一可以成功的方法是在类型之间有一个自定义转换运算符。情况可能是这样。但是在处理泛型类型时,不会处理自定义转换运算符。

        【讨论】:

          【解决方案5】:

          Convert 类的存在正是为了这个目的。

          private Ttgt MyMethod<Tsrc, Ttgt>(Tsrc SourceObject)
              where Tsrc : struct
              where Ttgt : struct
          {
              return (Ttgt) Convert.ChangeType(SourceObject, typeof(Ttgt));
          }
          

          还请注意,您可以这样做:

              return (Ttgt) (object) SourceObject;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-07-14
            • 1970-01-01
            • 1970-01-01
            • 2018-03-05
            • 1970-01-01
            相关资源
            最近更新 更多