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个类型