将子类转换为其超类,但仍然能够使用子类方法和属性

时间:2015-04-03 13:55:10

标签: c#

我试图找到一种方法将类强制转换为其超类,并仍然使用该类公开的方法和属性。检查以下代码;

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;
    }
}

汽车,奥迪,宝马课程是该框架的一部分,我无法改变这些。这个框架要么返回奥迪或宝马(或许多其他人之一)。

要获得里程,我不想为所有可能的品牌创建完全相同的方法。但是当我把它投射到它的超类时,我再也无法访问里程属性了......

我该如何解决这个问题?

5 个答案:

答案 0 :(得分:3)

看起来框架的设计很差。他们应该在所有支持追踪里程的界面上设置一个界面,以便你可以投射到那个(如果有的话)并从界面中提取里程数。

由于您提到无法控制框架类,因此您只有几个选项。您可以尝试检测其类型并将其投射以拉出里程或使用反射。后者可能是你最好的选择。

有关如何获取属性值的详细示例,请参阅Use reflection to get the value of a property by name in a class instance

对您来说最大的区别在于,您不确定“前程万里”属性是否存在,您需要在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);
    }

答案 1 :(得分:2)

看起来你必须与糟糕的框架作斗争。 克服这个问题的可能方法是使用反射或动态。如果有许多可能的值。如果你知道只有少数几种可能性,并且在这种情况下可以建立一个依赖关系,你可以检查确切的类型并转换为它。

答案 2 :(得分:0)

这是应该做的:

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;
    }
}

所有汽车的里程存在

答案 3 :(得分:0)

我会用反射来获取属性:

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;

答案 4 :(得分:-1)

多级继承是选项之一,试一试

公共类汽车 {

}

公共类MyCustomizedCar:Car { private int _Mileage;     public int Mileage     {         得到{return _Mileage; }         设置{_Mileage = value;}     } }

公共级别奥迪:MyCustomizedCar {

}

公共级宝马:MyCustomizedCar {

}