C# 这是一种优雅的方式吗?可能是仿制药吗?

C# 这是一种优雅的方式吗?可能是仿制药吗?,c#,generics,C#,Generics,我有两个派生类(Sale和ServiceCharge)。两者都是交易。如果我有一个BusinessService,我想为它创建一个ServiceCharge。如果我传递了一个产品,我想实例化Sale 这是我的想法 private void CreateInstance(object element) { Transaction transaction; if (element.GetType() == typeof(BussinessService)) {

我有两个派生类(Sale和ServiceCharge)。两者都是交易。如果我有一个BusinessService,我想为它创建一个ServiceCharge。如果我传递了一个产品,我想实例化Sale

这是我的想法

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
,也不在问题中)