C# 如何在接口方法的实现中强制特定值?

C# 如何在接口方法的实现中强制特定值?,c#,.net,interface,C#,.net,Interface,用一个例子更好地解释了这一点。目前我有这样的想法: public class Car { internal string SaleCode {get; set;} //Spring, Summer, ... public string Name {get; set; } //Model name } public interface ICarFactory { Car GetSummerSaleCar(); Car GetSpringSaleCar(); }

用一个例子更好地解释了这一点。目前我有这样的想法:

public class Car {
    internal string SaleCode {get; set;} //Spring, Summer, ...
    public string Name {get; set; }  //Model name
}

public interface ICarFactory 
{
    Car GetSummerSaleCar();
    Car GetSpringSaleCar();
}

public class FordFactory : ICarFactory 
{
    public Car GetSummerSaleCar() {
        return new Car() {Name="Fiesta"};
    }
    public Car GetSpringSaleCar() {
        return new Car() {Name="Fusion"};
    }
}

public class CarProvider {
    public void ProduceCars(ICarFactory factory) {
        var inventory = new List<Car>();
        Car car = null;
        car = factory.GetSummerSaleCar();
        car.SaleCode = "SMR";
        inventory.Add(car);

        car = factory.GetSpringSaleCar();
        car.SaleCode = "SPG";
        inventory.Add(car);
    }
}
公车{
内部字符串SaleCode{get;set;}//春季、夏季。。。
公共字符串名称{get;set;}//模型名称
}
公共接口ICarFactory
{
Car GetSummerSaleCar();
Car GetSpringSaleCar();
}
公共类工厂:ICarFactory
{
公共汽车{
归还新车(){Name=“Fiesta”};
}
公共汽车{
归还新车(){Name=“Fusion”};
}
}
公共级汽车供应商{
公共车辆(ICarFactory工厂){
var inventory=新列表();
Car=null;
car=factory.GetSummerSaleCar();
car.SaleCode=“SMR”;
存货。添加(汽车);
car=factory.GetSpringSaleCar();
car.SaleCode=“SPG”;
存货。添加(汽车);
}
}
对于每种方法,car的SaleCode应始终相同,因此CarFactory实现不应设置此值。现在我在CarProvider类中设置了这个,但我想知道是否有办法将其从接口中去掉。我唯一能想到的是在接口内部使用一个应用于方法定义的属性,在这里我可以设置类型,但我觉得必须有另一种选择

想法

更新 如果您想知道,这就是我在提到向接口中的每个方法添加属性时所说的:

public class SaleAttribute : Attribute
{
    public string Code { get; set; }
}


public interface ICarFactory
{
    [Sale(Code = "SMR")]
    Car GetSummerSaleCar();
    [Sale(Code = "SPG")]
    Car GetSpringSaleCar();
}

public void ProduceCars(ICarFactory factory)
{
    var inventory = new List<Car>();
    foreach (var method in typeof(ICarFactory).GetMethods())
    {
        String carType = null;
        var attributes = method.GetCustomAttributes(typeof(SaleAttribute), false);
        if (attributes.Length == 1)
        {
            saleCode = ((SaleAttribute)attributes[0]).Name;
            Car car = (Car)method.Invoke(factory, null);
            car.SaleCode = saleCode;
            inventory.Add(car);
        }
    }
}
公共类属性:属性
{
公共字符串代码{get;set;}
}
公共接口ICarFactory
{
[销售(代码=“SMR”)]
Car GetSummerSaleCar();
[销售(Code=“SPG”)]
Car GetSpringSaleCar();
}
公共车辆(ICarFactory工厂)
{
var inventory=新列表();
foreach(typeof(ICarFactory).GetMethods()中的var方法)
{
字符串carType=null;
var attributes=method.GetCustomAttributes(typeof(SaleAttribute),false);
如果(attributes.Length==1)
{
saleCode=((SaleAttribute)属性[0])。名称;
Car=(Car)方法。Invoke(工厂,null);
car.SaleCode=SaleCode;
存货。添加(汽车);
}
}
}
这样做的另一个好处是,如果在接口中添加了方法,则无需修改CarProvider。缺点显然是与反射相关的开销(性能和维护)

更新2
我将示例从使用车型改为销售代码,因为这更好地反映了我的情况。

如何使用
CarType.Create(Medium)
而不是
新车

我建议创建一个名为
CarType

public class CarType{
   public class CarType(instName){
      this.instName = instName;
   }
   public Car Create(){
      return new Car(){Type=instName;}
      //or alternatively, if you have more implementations for the cars
      //return (Car)Activator.CreateInstance(this.instName);
   }
   public static CarType Compact = new CarType("Compact");
   public static CarType Medium = new CarType("Medium");
}
而且用法是

Medium.Create(){Name="Fiesta";}

但这仍然是CarFactory的方法,因此对您没有太大帮助…

如何
CarType.创建(中等)
而不是
新车

我建议创建一个名为
CarType

public class CarType{
   public class CarType(instName){
      this.instName = instName;
   }
   public Car Create(){
      return new Car(){Type=instName;}
      //or alternatively, if you have more implementations for the cars
      //return (Car)Activator.CreateInstance(this.instName);
   }
   public static CarType Compact = new CarType("Compact");
   public static CarType Medium = new CarType("Medium");
}
而且用法是

Medium.Create(){Name="Fiesta";}

但是这仍然在CarFactorys方法中,因此对您没有太大帮助…

Mike我认为最好的方法是使用一个抽象类型的Car和两个派生类:CompactCar和MediumCar

public abstract class Car { 
    internal string Type {get; protected set;} //Compact, Medium, Large, ... 
    public string Name {get; set; }  //Model name 
} 

public class CompactCar : Car
{
     public CompactCar() { this.Type = "Compact"; }
}

public class MediumCar : Car
{
     public MediumCar() { this.Type = "Compact"; }
}
因此,您可以返回特定类型,如:

public interface ICarFactory      
{     
    CompactCar GetCompact();     
    MediumCar GetMedium();     
}  
public class FordFactory : ICarFactory    
{   
    public CompactCar GetCompact() {   
        return new CompactCar() {Name="Fiesta"};   
    }   
    public MediumCar GetMedium() {   
        return new MediumCar() {Name="Fusion"};   
    }   
}  

这对使用它的源代码的影响最小,因为它仍然可以引用具有抽象类型Car的Car。

Mike我认为最好的方法是拥有一个抽象类型Car和两个派生类:CompactCar和MediumCar

public abstract class Car { 
    internal string Type {get; protected set;} //Compact, Medium, Large, ... 
    public string Name {get; set; }  //Model name 
} 

public class CompactCar : Car
{
     public CompactCar() { this.Type = "Compact"; }
}

public class MediumCar : Car
{
     public MediumCar() { this.Type = "Compact"; }
}
因此,您可以返回特定类型,如:

public interface ICarFactory      
{     
    CompactCar GetCompact();     
    MediumCar GetMedium();     
}  
public class FordFactory : ICarFactory    
{   
    public CompactCar GetCompact() {   
        return new CompactCar() {Name="Fiesta"};   
    }   
    public MediumCar GetMedium() {   
        return new MediumCar() {Name="Fusion"};   
    }   
}  


这对使用它的源代码的影响最小,因为它仍然可以引用具有抽象类型Car的cars。

一个实现接口并设置Car类型的抽象基类如何?在创建Car对象期间无法设置类型的任何特定原因?您可以在Car类中自动设置值,或者使用抽象类而不是接口。您的FordFactory也没有实现ICarFactory。@TimMedora:抽象类是可能的,但我知道,您将如何实现它?我只能想到有一个抽象的方法OnGetCompact,我可以从我的GetCompact方法调用它。因此,基本上,每种车型都有一对方法(一个公共方法和一个抽象方法)。我不确定我是否喜欢。请看@Jaime Olivares solution。我正要发布一些类似的东西(经过思考,我更喜欢它,而不是使用抽象基类)。一个实现接口并设置汽车类型的抽象基类如何?在创建汽车对象期间无法设置类型的任何特殊原因?您可以在汽车类中自动设置值,或者使用抽象类而不是接口。您的FordFactory也没有实现ICarFactory。@TimMedora:抽象类是可能的,但我知道,您将如何实现它?我只能想到有一个抽象的方法OnGetCompact,我可以从我的GetCompact方法调用它。因此,基本上,每种车型都有一对方法(一个公共方法和一个抽象方法)。我不确定我是否喜欢。请看@Jaime Olivares solution。我正准备发布一些类似的东西(经过思考,我更喜欢它,而不是使用抽象基类)。具体的汽车工厂不应该能够设置汽车类型。我将CarType定义为具有设置类型的汽车工厂。。。我在想这本书中的“类型为工厂”模式:你能详细说明一下吗?我在你链接到的pdf中没有看到太多细节。混凝土汽车工厂不应该能够设置汽车类型。我将汽车类型设置为具有设置类型的汽车的工厂。。。我在想这本书中的“类型为工厂”模式:你能详细说明一下吗?我在你链接到的pdf中没有看到太多细节。这绝对是一个不错的选择。唯一的问题是,在我的实际实现中,我实际上有10到15个类型,这意味着创建10到15个类型