C# 铸造类<;T>;上课

C# 铸造类<;T>;上课,c#,generics,casting,C#,Generics,Casting,我有一个简单的类,它看起来像这样: public class MyClass<T> { public int Status { get; set; } public T Value { get; set; } } 我希望能够将MyClass转换为MyClass,默认情况下这似乎不起作用。此示例强制转换引发以下错误: MyClass<string> withT = new MyClass<string> { Status = 1, Value

我有一个简单的类,它看起来像这样:

public class MyClass<T> 
{
    public int Status { get; set; }
    public T Value { get; set; }
}
我希望能够将
MyClass
转换为
MyClass
,默认情况下这似乎不起作用。此示例强制转换引发以下错误:

MyClass<string> withT = new MyClass<string> { Status = 1, Value = "Somevalue" };
MyClass withoutT = (MyClass)withT;
MyClass withT=newmyclass{Status=1,Value=“Somevalue”};
MyClass without t=(MyClass)withT;
无法将类型为“MyClass`1[System.String]”的对象强制转换为“MyClass”

因此,我认为我需要实现一些隐式/显式转换逻辑,如中所述

我更新了
MyClass
如下,但是仍然抛出相同的错误:

public class MyClass<T>
{
    public int Status { get; set; }
    public T Value;

    public static implicit operator MyClass(MyClass<T> myClass)
    {
        return new MyClass
        {
            Status = myClass.Status,
            Value = myClass.Value.GetType() == typeof(string) ? myClass.Value.ToString() : null
        };
    }
}
公共类MyClass
{
公共int状态{get;set;}
公共价值观;
公共静态隐式运算符MyClass(MyClass MyClass)
{
返回新的MyClass
{
Status=myClass.Status,
Value=myClass.Value.GetType()==typeof(字符串)?myClass.Value.ToString():null
};
}
}

有人能帮我指出哪里出了问题吗?

为什么不使用工厂?下面是一个非常简单的示例:

public static class MyClass
{
    public static MyClass<string> Create(string s, int status)
    {
        return new MyClass<string>(s, status);
    }
}

...

var x = MyClass.Create("Foo", 0);
公共静态类MyClass
{
公共静态MyClass创建(字符串s,int状态)
{
返回新的MyClass,状态;
}
}
...
var x=MyClass.Create(“Foo”,0);

为什么不使用工厂?下面是一个非常简单的示例:

public static class MyClass
{
    public static MyClass<string> Create(string s, int status)
    {
        return new MyClass<string>(s, status);
    }
}

...

var x = MyClass.Create("Foo", 0);
公共静态类MyClass
{
公共静态MyClass创建(字符串s,int状态)
{
返回新的MyClass,状态;
}
}
...
var x=MyClass.Create(“Foo”,0);

乔恩·斯凯特的评论是正确的

完全抛弃泛型。你能做到吗

class X {}
class Y : X {}
...
var x = new X();
var y = (Y)x;
不,你不能。
X
不是
Y
。类似地,
MyClass
也不是
MyClass

进一步说,您的强制转换代码仍然不能像您所说的那样工作,并且尝试以其他方式定义隐式或显式强制转换运算符(例如,专门使用
字符串键入
)甚至无法编译

解决方案

  • 做l33t的解决方案。这是最直截了当的
  • 执行@ja72的解决方案。它是最通用的
  • 创建自己的执行转换的静态方法或创建执行转换的扩展方法
  • MyClass
    中断对
    MyClass
    的继承,并定义运算符。是的,这意味着一些冗余代码

    • 乔恩·斯凯特的评论是正确的

      完全抛弃泛型。你能做到吗

      class X {}
      class Y : X {}
      ...
      var x = new X();
      var y = (Y)x;
      
      不,你不能。
      X
      不是
      Y
      。类似地,
      MyClass
      也不是
      MyClass

      进一步说,您的强制转换代码仍然不能像您所说的那样工作,并且尝试以其他方式定义隐式或显式强制转换运算符(例如,专门使用
      字符串键入
      )甚至无法编译

      解决方案

      • 做l33t的解决方案。这是最直截了当的
      • 执行@ja72的解决方案。它是最通用的
      • 创建自己的执行转换的静态方法或创建执行转换的扩展方法
      • MyClass
        中断对
        MyClass
        的继承,并定义运算符。是的,这意味着一些冗余代码

      考虑将
      MyClass
      设置为必须继承类(使用
      abstract
      关键字),这样它就不能被实例化。这样,您只能从派生类创建对象,而派生类可以向下转换为基类

      此外,如果您想要对派生类型(用于转换)的类型引用,请将其包含在类型参数中。添加一个从MyClass继承的
      t派生的
      ,如下所示:

      public abstract class MyClass<TDerived, TValue> where TDerived : MyClass<TDerived, TValue>
      {
          protected MyClass(int status, TValue value)
          {
              this.Status = status;
              this.Value = value;
          }
          public int Status { get; set; }
          public TValue Value { get; set; }
      
          public static implicit operator TDerived(MyClass<TDerived, TValue> myClass)
              => myClass as TDerived;
      }
      
      public class SpecificClass : MyClass<SpecificClass, string>
      {
          public SpecificClass(int status, string value) : base(status, value)
          {
              // The ONLY way to instantiate a MyClass<> is from a derived class
              // such as this.
          }        
      }
      
      class Program
      {
          static void Main(string[] args)
          {
              MyClass<SpecificClass, string> my_class = new SpecificClass(-1, "ABC");
      
              SpecificClass my_specific = my_class;
          }
      }
      
      公共抽象类MyClass,其中TDerived:MyClass
      {
      受保护的MyClass(int状态,TValue值)
      {
      这个状态=状态;
      这个。值=值;
      }
      公共int状态{get;set;}
      公共TValue值{get;set;}
      公共静态隐式运算符TDerived(MyClass MyClass)
      =>导出的myClass;
      }
      公共类SpecificClass:MyClass
      {
      公共SpecificClass(int状态,字符串值):基(状态,值)
      {
      //实例化MyClass的唯一方法是从派生类
      //像这样。
      }        
      }
      班级计划
      {
      静态void Main(字符串[]参数)
      {
      MyClass my_class=新的SpecificClass(-1,“ABC”);
      SpecificClass my_specific=我的_类;
      }
      }
      
      考虑将
      MyClass
      设置为必须继承类(使用
      abstract
      关键字),这样它就不能被实例化。这样,您只能从派生类创建对象,而派生类可以向下转换为基类

      此外,如果您想要对派生类型(用于转换)的类型引用,请将其包含在类型参数中。添加一个从MyClass继承的
      t派生的
      ,如下所示:

      public abstract class MyClass<TDerived, TValue> where TDerived : MyClass<TDerived, TValue>
      {
          protected MyClass(int status, TValue value)
          {
              this.Status = status;
              this.Value = value;
          }
          public int Status { get; set; }
          public TValue Value { get; set; }
      
          public static implicit operator TDerived(MyClass<TDerived, TValue> myClass)
              => myClass as TDerived;
      }
      
      public class SpecificClass : MyClass<SpecificClass, string>
      {
          public SpecificClass(int status, string value) : base(status, value)
          {
              // The ONLY way to instantiate a MyClass<> is from a derived class
              // such as this.
          }        
      }
      
      class Program
      {
          static void Main(string[] args)
          {
              MyClass<SpecificClass, string> my_class = new SpecificClass(-1, "ABC");
      
              SpecificClass my_specific = my_class;
          }
      }
      
      公共抽象类MyClass,其中TDerived:MyClass
      {
      受保护的MyClass(int状态,TValue值)
      {
      这个状态=状态;
      这个。值=值;
      }
      公共int状态{get;set;}
      公共TValue值{get;set;}
      公共静态隐式运算符TDerived(MyClass MyClass)
      =>导出的myClass;
      }
      公共类SpecificClass:MyClass
      {
      公共SpecificClass(int状态,字符串值):基(状态,值)
      {
      //实例化MyClass的唯一方法是从派生类
      //像这样。
      }        
      }
      班级计划
      {
      静态void Main(字符串[]参数)
      {
      MyClass my_class=新的SpecificClass(-1,“ABC”);
      SpecificClass my_specific=我的_类;
      }
      }
      
      您已经创建了
      MyClass
      的实例。这不是
      MyClass
      的实例。这就像尝试这样做:
      objectx=newobject();字符串y=(字符串)x。如何定义非泛型的
      MyClass
      ?每个
      MyClass
      都是
      MyClass
      ,但不是每个
      MyClass
      都是
      MyClass