使用接口时访问类上的属性

时间:2015-06-03 08:51:22

标签: c# .net

我做了这个小控制台应用程序来说明我的问题。

我想知道是否有办法访问类的属性,这是您正在使用的接口的当前实现。在下面的这个例子中,我想设置车辆界面属性Engine,如果它是一辆汽车。当你做一个新的汽车实例时,我找到了一种方法来使用括号,但是我想稍后通过做车来做到这一点。发动机="东西&#34 ;;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        var car = (Car)GetVehicle(VehicleType.Car);

        var bike = (Bike)GetVehicle(VehicleType.Bike);

        Console.ReadKey();
    }



    static IVehicle GetVehicle(VehicleType type)
    {
        IVehicle vehicle = null;

        switch (type)
        {
            case VehicleType.Car:
                vehicle = new Car() { Engine = "V8", Name = "Car Name" };//Works
                vehicle.Engine = "cannot do this"; //This does not work
                break;
            case VehicleType.Bike:
                vehicle = new Bike() { Mountainbike = true, Name = "Bike name" }; // Works
                vehicle.Mountaikbike = true; //This does not work either, same problem
                break;
            default:
                break;
        }

        return vehicle;
    }


}


public enum VehicleType
{
    Car, Bike
}


public class Car : IVehicle
{
    public string Name { get; set; }
    public string Engine { get; set; }

}

public class Bike : IVehicle
{
    public string Name { get; set; }
    public bool Mountainbike { get; set; }
}

public interface IVehicle
{
    string Name { get; set; }
}

}

5 个答案:

答案 0 :(得分:3)

即使您的GetVehicle()方法返回 IVechile,但并不意味着内部必须将返回的对象称为IVechile同样。它绝对可以将其称为实际(具体)类型,然后能够像往常一样访问其公共属性。

所以你可以这样做:

static IVehicle GetVehicle(VehicleType type)
{
    IVehicle ret = null;

    switch (type)
    {
        case VehicleType.Car:
            var car = new Car() { Name = "Car Name" };
            car.Engine = "V8";
            ret = car;
            break;
        case VehicleType.Bike:
            var bike = new Bike() { Name = "Bike name" }; 
            bike.Mountainbike = true;
            ret = bike;
            break;
    }

    return ret;
}

甚至更短:

static IVehicle GetVehicle(VehicleType type)
{
    switch (type)
    {
        case VehicleType.Car:
            return new Car() { Engine = "V8", Name = "Car Name" };
        case VehicleType.Bike:
            return new Bike() { Mountainbike = true, Name = "Bike name" }; 
    }

    return null;
}

答案 1 :(得分:3)

这被称为'漏洞抽象'并且不应该这样做:((Car)vehicle).Engine =" ..."。您的代码应该处理契约(接口)而不是具体的实现(类)。

在这种情况下,您应该创建一个ICar接口,该接口扩展IVehicle并使用它来公开Engine属性并测试您的IVehicle是否暴露了ICar。这样很多东西都可以被视为IVehicle,ICar是一种可以更具体处理的专业化。

答案 2 :(得分:2)

要回答以后如何操作的问题,如果你有像

这样的代码
IVehicle vehicle= GetVehicle(VehicleType.Car);

// cast car 
Car car = vehicle as Car;

if (car != null)
{
 car.Engine = "V8";
}

基本上IVehicle没有'Engine'作为属性。它是添加了汽车类型的东西。因此,您需要将您的IVehicle投射到汽车并检查它是否真的是一辆汽车。如果是,则设置它。

如果您认为很多车辆需要引擎,那么您可以这样做:

public interface IVehicleWithEngine :IVehicle
{
 string Engine { get; set; }
}

让汽车和其他“引擎”车辆实现它。

答案 3 :(得分:1)

问题是由您启动车辆的位置引起的,您可以从交换机返回,因为这是您在方法中所做的一切。

switch (type)
{
    case VehicleType.Car:
        return new Car() { Engine = "V8", Name = "Car Name" };
        break;
    case VehicleType.Bike:
        return new Bike() { Mountainbike = true, Name = "Bike name" }; 
        break;
    default:
        break;
}
return null;

答案 4 :(得分:-2)

你可以这样写:

((Car)vehicle).Engine = "what you want";

只需在需要时投射对象。