【问题标题】:Cast generic class object to non-generic将泛型类对象转换为非泛型
【发布时间】:2022-01-12 17:05:05
【问题描述】:

我有 2 节课:

public class GenericClass<T>
{
   public T Item {get;set;}
}
public class StringClass
{
  public string Item {get;set;}
}

现在我有一个 GenericClass 对象,我需要将它转换为 StringClass 对象:

var genericObj = new GenericClass<string>();
var stringObj = (StringClass)genericObj; // <---

如何将泛型类转换为特定类?

【问题讨论】:

  • 这听起来像是 AutoMapper 的工作。

标签: c# casting type-conversion


【解决方案1】:

您不能将一种类型转换为另一种类型,因为这些类型是不相关的。

但是,您可以定义 conversion operator:

public class StringClass
{
    public string Item { get; set; }
    
    public static explicit operator StringClass(GenericClass<string> generic)
        => new StringClass { Item = generic.Item };
}

这将允许这种语法:

var genericObj = new GenericClass<string>();
var stringObj = (StringClass)genericObj;

【讨论】:

    【解决方案2】:

    你不能。您需要通用继承类型或实现接口。

    继承:

    public class GenericClass<T>
    {
       public T Item {get;set;}
    }
    public class StringClass : GenericClass<string>
    {
    }
    

    【讨论】:

      【解决方案3】:

      如果你真的需要它,你可以这样做

      var stringObj = new  StringClass(genericObj);
      
      public class StringClass
      {
          public string Item { get; set; }
          
          public StringClass(GenericClass<string> genericClass)
          {
              Item=genericClass.Item;
          }
       
         public StringClass(){}
      }   
      

      或者这样更灵活

      public interface IGenericClass<T>
      {
          public T Item { get; set; }
      }
      public class GenericClass<T>:IGenericClass<T>
      {
          public T Item { get; set; }
      }
      public class StringClass
      {
          public string Item { get; set; }
          
          public StringClass(IGenericClass<string> genericClass)
          {
              Item=genericClass.Item;
          }
         
          public StringClass(){}
      }
      

      【讨论】:

        【解决方案4】:

        使用this answer

        var genericObj = new GenericClass<string>();
        var stringObj = (StringClass)Convert.ChangeType(genericObj, typeof(StringClass));
        

        【讨论】:

        • 这会绕过试图阻止这种情况发生的编译器检查,从而产生InvalidCastException
        【解决方案5】:

        最后我用ICloneable解决了,

        这里有一个名为 GenericClass 的基类、一个名为 GenericClassT 的泛型类和一个名为 StringClass 的类。

        继承是:

        GenericClass GenericClassT StringClass

        在 GenericClass 和 GenericClassT 上使用 ICloneable 实现,添加 CreateObject 和 CopyTo 方法我达到了最终目标:

        var genericObj = new GenericClass<string>();
        var stringObj = (StringClass)genericObj.Clone<StringClass>();
        

        类定义:

        public class GenericClass: ICloneable
        {
            public string Id {get;set;}
        
            protected virtual ApiRequestResult CreateObject()
            {
                return new GenericClass();
            }
            protected virtual void CopyTo(GenericClass obj)
            {
                obj.Id = Id;
            }
            public virtual object Clone()
            {
                var obj = CreateObject();
        
                CopyTo(obj);
        
                return obj;
            }
            public virtual object Clone<T>() where T: GenericClass
            {
                var obj = (GenericClass)Activator.CreateInstance(typeof(T));
        
                CopyTo(obj);
        
                return obj;
            }
        }
        
        public class GenericClass<T>: GenericClass
        {
            public T Data {get; set;}
        
            protected override GenericClass CreateObject()
            {
                return new GenericClass<T>();
            }
            protected override void CopyTo(GenericClass obj)
            {
                base.CopyTo(obj);
                ((GenericClass<T>)obj).Data = Data;
            }
        }
        
        public class StringClass: GenericClass<string>
        {
            
        }
        

        【讨论】:

        • 现在automapper可以休息了。我们不再需要它们了。你已经完成了替代方案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-08
        相关资源
        最近更新 更多