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