C# 这是一种优雅的方式吗?可能是仿制药吗?
我有两个派生类(Sale和ServiceCharge)。两者都是交易。如果我有一个BusinessService,我想为它创建一个ServiceCharge。如果我传递了一个产品,我想实例化Sale 这是我的想法C# 这是一种优雅的方式吗?可能是仿制药吗?,c#,generics,C#,Generics,我有两个派生类(Sale和ServiceCharge)。两者都是交易。如果我有一个BusinessService,我想为它创建一个ServiceCharge。如果我传递了一个产品,我想实例化Sale 这是我的想法 private void CreateInstance(object element) { Transaction transaction; if (element.GetType() == typeof(BussinessService)) {
private void CreateInstance(object element)
{
Transaction transaction;
if (element.GetType() == typeof(BussinessService))
{
transaction = new ServiceCharge((BussinessService)element))
}
else
{
transaction = new Sale((Product)element);
}
{
你能告诉我一种更优雅的方式吗?我知道如何使用只有一个构造函数的泛型
private void CreateInstance<T>(T element)
{
Transaction transaction = new Transaction((T)element);
}
private void CreateInstance(T元素)
{
交易=新交易((T)元素);
}
但我不知道如何处理第一种情况。定义这样的通用接口:
public interface ITransactionable<T>
where T : Transaction
{
T CreateTransaction();
}
现在,您的通用方法可以定义为:
private void CreateInstance<T>(ITransactionable<T> element)
{
Transaction transaction = element.CreateTransaction();
...
}
private void CreateInstance(ITransactionable元素)
{
Transaction=element.CreateTransaction();
...
}
定义如下的通用接口:
public interface ITransactionable<T>
where T : Transaction
{
T CreateTransaction();
}
现在,您的通用方法可以定义为:
private void CreateInstance<T>(ITransactionable<T> element)
{
Transaction transaction = element.CreateTransaction();
...
}
private void CreateInstance(ITransactionable元素)
{
Transaction=element.CreateTransaction();
...
}
在这种情况下,一个简单的界面也可以工作:
interface ITransactionable
{
Transaction CreateTransaction();
}
class BusinessService : ITransactionable
{
public Transaction CreateTransaction() { return new ServiceCharge( this ); }
}
class Product : ITransactionable
{
public Transaction CreateTransaction() { return new Sale( this ); }
}
在这种情况下,只有一个普通接口也可以工作:
interface ITransactionable
{
Transaction CreateTransaction();
}
class BusinessService : ITransactionable
{
public Transaction CreateTransaction() { return new ServiceCharge( this ); }
}
class Product : ITransactionable
{
public Transaction CreateTransaction() { return new Sale( this ); }
}
只需创建两种不同的方法:
private void CreateInstance(Product product)
{
Transaction transaction = new Sale(product);
}
private void CreateInstance(BusinessService service)
{
Transaction transaction = new ServiceCharge(service);
}
编译器将根据您使用的参数类型知道您调用了什么方法。只需创建两个不同的方法:
private void CreateInstance(Product product)
{
Transaction transaction = new Sale(product);
}
private void CreateInstance(BusinessService service)
{
Transaction transaction = new ServiceCharge(service);
}
编译器将根据您使用的参数类型知道您调用了什么方法。
BusinessService
和Product
应该在某种程度上是多态的,可能是通过共享一个接口,比如
interface IChargable<out T> where T : Transaction
{
Transaction Charge();
}
接口ICharable,其中T:事务
{
交易费用();
}
这样实现的接口
class BusinessService : IChargable<ServiceCharge>
{
public ServiceCharge Charge()
{
return new ServiceCharge(...
}
}
class Product : IChargable<Sale>
{
public Sale Charge()
{
return new Sale(...
}
}
class-BusinessService:IChargable
{
公共服务费
{
返回新服务费用(。。。
}
}
类别产品:IChargable
{
公开销售费用()
{
返回新销售(。。。
}
}
这意味着像这样的代码可以工作
var chargables = new IChargable<Transaction>[]
{
new BusinessService(),
new Product()
};
var transactions = chargables.Select(c => c.Charge());
var chargables=new IChargable[]
{
新业务服务(),
新产品()
};
var transactions=chargables.Select(c=>c.Charge());
业务服务
和产品
应该在某种程度上具有多态性,可能是通过共享一个界面,比如
interface IChargable<out T> where T : Transaction
{
Transaction Charge();
}
接口ICharable,其中T:事务
{
交易费用();
}
这样实现的接口
class BusinessService : IChargable<ServiceCharge>
{
public ServiceCharge Charge()
{
return new ServiceCharge(...
}
}
class Product : IChargable<Sale>
{
public Sale Charge()
{
return new Sale(...
}
}
class-BusinessService:IChargable
{
公共服务费
{
返回新服务费用(。。。
}
}
类别产品:IChargable
{
公开销售费用()
{
返回新销售(。。。
}
}
这意味着像这样的代码可以工作
var chargables = new IChargable<Transaction>[]
{
new BusinessService(),
new Product()
};
var transactions = chargables.Select(c => c.Charge());
var chargables=new IChargable[]
{
新业务服务(),
新产品()
};
var transactions=chargables.Select(c=>c.Charge());
元素应该是多态的。由于元素名称不正确,我无法提供基于代码的修复。BusinessService
和产品是否以某种方式具有多态性?它们实现了公共接口还是共享了共同祖先?元素应该是多态的。因为元素名称不正确,我无法提供基于代码的修复。是否BusinessService
和Product
在某种程度上是多态的?它们实现了一个共同的接口还是共享了一个共同的祖先?+1是的,这是真的。代码OP中没有任何东西需要它是泛型的。这稍微简单一点,但是.NET中的接口名称。我同意。我认为泛型使它更加复杂,而没有添加任何值。我试图将此作为一个答案,但泛型可以为您提供一个专门的回报类型,这可能是有益的。这是真的,但也不是这里特别需要的。我选择简单多态解决方案的原因是基于这样一个想法,即如果它达到了要求,越简单越好!:)非常感谢!我想我需要训练我糟糕的OOP能力。这个解决方案给了我很多新想法:)+1是的,这是真的。OP显示的代码中没有任何东西需要它是泛型的。这稍微简单一点,但是.NET中的接口名称。我同意。我认为泛型会使它更复杂,而不会增加任何值。我试图将此作为一个答案,但泛型可以为您提供一个专门的返回类型,这可能是有益的。这就是这是真的,但也不是这里特别需要的。我之所以选择简单多态解决方案,是基于这样一个想法:如果它达到了要求,越简单越好!:)非常感谢!我想我需要训练我糟糕的OOP能力。这个解决方案给了我很多新想法:)一个关键,它不是协变的。否则,我们得到了相同的答案。虽然我更喜欢我的语义,但我无法理解OP的想法。如果接口不是协变的,您将很难创建一个IEnumerable
,它显然对基于集合的操作或任何多态linq活动都很有用。也许可以将其命名为ITransactionableFactory
,因为这看起来像是Factory Patternone critisicm,它不是协变的。否则,我们得到了相同的答案。虽然我更喜欢我的语义学,但我无法理解OP的想法。如果接口不是协变的,制作一个显然对基于集合的操作或任何多态linq活动都有用的IEnumerable
会有困难。也许可以将其命名为ITransactionableFactory
,因为这看起来像工厂模式,以便工作,IChargable.Charge
的声明返回类型应为T
而不是Transaction
@JeanHominal,但不存在T
类型T
与Transaction
具有多态性。代码确实有效,因为IChargable
对于T
@JeanHominal是协变的,所以不能用类型参数的名称声明变量,除非它恰好是有效的类型(不太可能是T
,也不在问题中)