C# 将子类强制转换为其超类,但仍然能够使用子类方法和属性
我试图找到一种方法将一个类强制转换为它的超类,并且仍然使用该类公开的方法和属性。检查下面的代码C# 将子类强制转换为其超类,但仍然能够使用子类方法和属性,c#,C#,我试图找到一种方法将一个类强制转换为它的超类,并且仍然使用该类公开的方法和属性。检查下面的代码 public class Car { } public class Audi : Car { private int _Mileage; public int Mileage { get { return _Mileage; } set { _Mileage = value;} } } public class BMW
public class Car
{
}
public class Audi : Car
{
private int _Mileage;
public int Mileage
{
get { return _Mileage; }
set { _Mileage = value;}
}
}
public class BMW : Car
{
private int _Mileage;
public int Mileage
{
get { return _Mileage; }
set { _Mileage = value;}
}
}
public class Program
{
//outside this class either a BMW class or Audi class is instantiated
Audi _newCar = new Audi();
// I don't know which one it is so I use a generic type
Car MyCar;
int Mileage;
Program()
{
// Now I cast the unknown class to the car type
MyCar = _newCar;
// Although I know both Audi & BMW have the Mileage property, I cannot use it
Mileage = MyCar.Mileage;
}
}
汽车、奥迪、宝马类是框架的一部分,我无法更改它们。此框架要么返回一辆奥迪或宝马(或其他众多车型之一)
为了获得里程数,我不想为所有可能的品牌创建完全相同的方法。但是,当我将它转换到它的超类时,我再也不能访问Milege属性了
我应该如何解决这个问题?这是应该如何解决的:
public class Car
{
public int Mileage
{
get ;
set ;
}
}
public class Audi : Car
{
public override string ToString()
{
return "I'm a Audi";
}
}
public class BMW : Car
{
public override string ToString()
{
return "I'm a BMW";
}
}
public class Program
{
//outside this class either a BMW class or Audi class is instantiated
Audi _newCar = new Audi();
// I don't know which one it is so I use a generic type
Car MyCar;
int Mileage;
Program()
{
// Now I cast the unknown class to the car type
MyCar = _newCar;
// Although I know both Audi & BMW have the Mileage property, I cannot use it
Mileage = MyCar.Mileage;
}
}
这是所有汽车的里程数看起来框架设计得很糟糕。他们应该在所有支持里程跟踪的系统上都设置一个界面,这样你就可以在可用的情况下进行转换,并从界面中提取里程 由于您提到没有对框架类的控制权,所以您只有几个选项。您可以尝试检测其类型并将其投射以提取里程数,也可以使用反射。后者可能是你最好的选择 有关如何获取属性值的示例,请参见 对您来说,最大的区别在于,因为您不确定Miledge属性是否存在,所以需要在调用
type.GetProperty(…)
之后进行检查
编辑以添加样本
使用反射:
static void Main(string[] args)
{
Audi _newCar = new Audi() { Mileage = 10 };
Car myCar = _newCar;
// Using Reflection
var propInfo = myCar.GetType().GetProperty("Mileage");
if (propInfo != null)
{
Console.WriteLine(propInfo.GetValue(myCar));
}
// Using dynamic
dynamic myCarDyn = myCar;
Console.WriteLine(myCarDyn.Mileage);
}
多级继承是一种选择,试试吧 公车 { } 公共类MyCustomizedCar:Car { 私人国际里程; 公共国际里程 { 获取{return} 设置{u里程=值;} } } 大众级奥迪:MyCustomizedCar { } 大众级宝马:MyCustomizedCar {
}看起来您必须与糟糕的框架作斗争。
克服这一问题的可能方法是使用反射或动态。如果有许多可能的值。如果您知道只有少数几种可能性,并且在此上下文中可以建立对它们的依赖关系,那么您只需检查确切的类型并对其进行强制转换。我将使用反射来获取属性:
try
{
Mileage = (int)MyCar.GetType().GetProperty("Mileage").GetValue(MyCar, null);
}
catch (Exception e)
{
// in this case, the instance has no property named "Mileage"
}
不要忘记导入正确的命名空间:
using System.Reflection;
嘿,托马斯,我知道。这就是为什么我解释说,汽车、奥迪和宝马是一个框架的一部分,我不能改变这一点。当你把
Car
I的代码放进去时,我想你可以改变它:/你为什么要选超类?框架是否返回一辆汽车或一辆奥迪/宝马?请确保我理解正确:您不能更改汽车或奥迪或宝马?很好,nodots。我不知道为什么我在最初的回答中盲目地发现了这个选项。嘿,特拉维斯,我知道这个属性对于可以给出的每个类都存在。我不知道如何将你给出的链接转换成这个例子。你能给我一个这个设置的例子吗?我使用了动态方法,它工作得非常出色。我已经重写了代码,可以删除近50%!我确实必须引用Microsoft.CSharp才能使其工作,并更改一些方法,使其参数转换为特定类型才能使Linq工作,但它的工作方式很有魅力。谢谢嘿,Treze,如果我强制转换为确切的类型,这意味着我必须对代码中所有可能的类型进行更改,对吗?