提问人:UK Rock 提问时间:12/20/2022 更新时间:12/20/2022 访问量:69
将子类转换为另一个具有基类的子类
cast child class to another with base class
问:
我需要一些长度单位可以将它们转换在一起
长度类作为父级 米、厘米、毫米作为孩子:
public abstract class Length
{
}
public class Meter: Length
{
public Meter(double val)
{
Value = val;
}
public double Value { get; set; }
public static explicit operator Centimeter(Meter m)
{
return new Centimeter(m.Value * 100);
}
public static explicit operator Millimeter(Meter m)
{
return new Millimeter(m.Value * 1000);
}
}
public class Centimeter: Length
{
public Centimeter(double val)
{
Value = val;
}
public double Value { get; set; }
public static explicit operator Meter(Centimeter cm)
{
return new Meter(cm.Value / 100);
}
public static explicit operator Millimeter(Centimeter cm)
{
return new Millimeter(cm.Value * 10);
}
}
public class Millimeter: Length
{
public Millimeter(double val)
{
Value = val;
}
public double Value { get; set; }
public static explicit operator Meter(Millimeter mm)
{
return new Meter(mm.Value / 1000);
}
public static explicit operator Centimeter(Millimeter mm)
{
return new Centimeter(mm.Value / 10);
}
}
我可以用这个代码将米转换为毫米:
Meter m = new Meter(3)
Millimeter mm = (Millimeter)m; //it's ok. result is 3000
但是我需要有基类类型来保存我的变量:
Length l;
if (true)
l = new Meter(3);
else
l = new Centimeter(20)
Millimeter m = (Millimeter)l;//runtime Error
我收到运行时错误: System.InvalidCastException:“无法将”米“类型的对象强制转换为”毫米“类型。
答:
0赞
DRapp
12/20/2022
#1
这可能是你希望得到的方向。让一个类能够整体处理毫米、厘米或米的转换。在本类示例中,我让类将值存储到最低粒度的毫米。现在,也就是说,你甚至可能希望毫米级别降低到整数与双倍,除非你想允许毫米的分数,但你可以选择。
public class MyLength
{
// always store at the lowest possible scale here
private double _millsValue;
private MyLength( double alwaysMillimeters)
{
_millsValue = alwaysMillimeters;
}
// have constructor return a MyLength based on whatever type wanted with
// the STATIC method name make sure it builds out to proper millimeter reference
public static MyLength Millimeter( double val)
{ return new MyLength(val); }
// 10 millimeters to 1 centimeter, so an incoming 5 centimeters = 50 millimeters
public static MyLength Centimeter( double val)
{ return new MyLength(val * 10); }
// similarly, 1000 millimeters to 1 meter, so 2 meters = 2000 millimeters
public static MyLength Meter (double val)
{ return new MyLength(val * 1000); }
// Now, expose public getter / setter that are bound to the
// underlying _millsValue and divide back out by 10 or 1000 respectively
public double Millimeters
{
get { return _millsValue; }
set { _millsValue = value; }
}
public double Centimeters
{
get { return _millsValue / 10; }
set { _millsValue = value * 10; }
}
public double Meters
{
get { return _millsValue / 1000; }
set { _millsValue = value * 1000; }
}
}
并展示如何应用和获取值,无论创建的基础如何,并通过 getters / setter 为您处理转换
public class LengthTest
{
public LengthTest()
{
var L = MyLength.Millimeter(1000);
var mm = L.Millimeters; // returns 1000
var cm = L.Centimeters; // returns 100
var m = L.Meters; // returns 1
var C = MyLength.Centimeter(3);
mm = C.Millimeters; // returns 30
cm = C.Centimeters; // returns 3
m = C.Meters; // returns .03
var M = MyLength.Meter(2);
mm = M.Millimeters; // returns 2000
cm = M.Centimeters; // returns 200
m = M.Meters; // returns 2
// can also SET values based on respective named getter/setter
var someVal = MyLength.Centimeter(0);
someVal.Centimeters = 250;
mm = someVal.Millimeters; // returns 2500
cm = someVal.Centimeters; // returns 250
m = someVal.Meters; // returns 2.5
someVal.Meters = .75;
mm = someVal.Millimeters; // returns 750
cm = someVal.Centimeters; // returns 75
m = someVal.Meters; // returns .75
someVal.Millimeters = 250;
mm = someVal.Millimeters; // returns 250
cm = someVal.Centimeters; // returns 25
m = someVal.Meters; // returns .25
}
}
评论
0赞
UK Rock
12/22/2022
感谢您的回答,您在此示例中是正确的,但我需要使用项目中的所有单位,例如位置转换器,将十进制值转换为度/分、分钟、UTM、MGRS 等。在这种情况下,每个单元都有特殊的变量、方法......我需要使用 cast 将它们转换在一起。
0赞
DRapp
12/22/2022
@UKRock,这就是这门课的重点。保存到一个共同的基础。然后,公开从任何基础转换为最终的方法。在这里,我可以通过提供毫米、厘米或米来创造,但作为回报,可以从任何一个获得。如果根据纬度/经度坐标与时间的相似输入提供位置对象,则存储在一个公共对象中,并通过其各自的公式获取另一个对象。你有没有尝试过这个代码示例?
0赞
UK Rock
12/24/2022
因此,如果我想获得度/分钟,我必须每次都将度转换为度/分钟。或者,如果我只想使用 UTM,我必须将 if 转换为度数作为基本单位。这对性能太差了
0赞
DRapp
12/24/2022
@UKRock,那么我会存储底层基础 AS 度/分钟。你能编辑你的帖子并显示你正在为你的UTM / Degree/Min上下文处理什么吗?我也会尝试编写一个类似的类来为您处理这个问题。
上一个:将派生类转换为基泛型类
下一个:如何将父类强制转换为子类
评论
toMillimeter()
Length
Meter
Millimeter
Length
Length
Length.FromMeters(5)