想象一下有一个整数
var aaa = (int)1; -------> here I have an int
var bbb = (object)aaa;-----> bbb is an object but the type is kept...
var ccc = aaa.GetType();---> ... in fact here I still have an integer
现在我定义了一个新的变量
var ddd = (object)2;
我想把它转换成与aaa相同的类型。ccc是一个类型,它的类型是integer但我不会
var ddd = (ccc)2;
因此,困扰我的是如何根据第一个变量的类型装箱第一个变量,然后取消装箱第二个变量
显然,我在这里用int做了这件事,但这件事可以扩展到任何类类型。
提前感谢
Patrick
您不能在运行时强键入变量。强类型(此处为int
(与周类型(object
(的优势在于,在编译时(或设计时(,您知道对象具有哪些成员,以及可以对其应用哪些操作。例如,如果aaa
是int
,您知道可以编写5 * aaa
。使用string
无法做到这一点。
aaa.GetType()
在运行时生成一个System.Type
对象!不能使用它强制转换另一个对象。你可以写一些类似的东西
??? ddd = Convert.ChangeType(bbb, aaa.GetType());
但你想把它分配给什么?ddd
的类型在编译时是未知的,您可以在代码中再次写入的唯一可能类型是object
。顺便说一句,ChangeType
返回一个object
。它还能返回什么?
请注意,var
关键字没有帮助。var
告诉编译器推断(强(静态类型(它当然在编译时这样做(。如果将鼠标悬停在这样一个变量上,Visual Studio编辑器将显示var
所代表的具体类型。
泛型类型总是在编译时解析。它们也于事无补。
对于数量有限的可能类型,可以使用switch表达式或switch语句根据类型执行适当的操作。
string message = bbb switch {
string s => $"bbb is the string '{s}' of length {s.Length}",
int i => $"10 times bbb is {10 * i}",
DateTime d => $"bbb is {d:yyyy-MM-dd HH:mm:ss}",
_ => "bbb has an unexpected type"
};
这使用了类型测试模式。
对于类类型,这有点不同。在这里你可以使用多态性。如果值类型(structs(实现了接口,那么这在一定程度上适用于它们。
多态性背后的思想是,你不需要知道对象的具体类型就可以用它做有意义的事情
public abstract class Shape
{
public abstract double Area();
}
public class Square : Shape
{
public double SideLength { get; set; }
public override double Area() => SideLength * SideLength;
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double Area() => Math.PI * Radius * Radius;
}
给定这些声明,您可以写:
private static void PrintArea(Shape shape)
{
Console.WriteLine(shape.Area());
}
和
var shapes = new List<Shape> {
new Circle { Radius = 4.5 },
new Square { SideLength = 7.0 }
};
foreach (Shape shape in shapes) {
PrintArea(shape);
}
你不需要知道你有什么样的形状,就可以确定它的面积。如果将来实现新的形状,则不必调整PrintArea
方法和foreach循环。