如何强迫我的班级使用T

时间:2018-12-07 04:20:54

标签: c# generics polymorphism

我已经和T一起上课了。

public interface ISendLogic<T> where T : NarcoticsResult
{
    ChangeType Change_New();
    ChangeType Change_Cancel();

    PurchaseType Purchase_New();
    PurchaseType Purchase_Cancel();     
}

public class SendLogic<T> : ISendLogic<T> where T : NarcoticsResult
{
    private eReportType _type;

    private bool Send_Change()
    {
        // Send to server by xml file
    }

    private bool Send_Purchase()
    {
        // Send to server by xml file
    }

    public ChangeType Change_New()
    {
        _type = change_new;
        Send_Change();
    }

    public ChangeType Change_Cancel()
    {
        _type = change_cancel;
        Send_Change();
    }

    public PurchaseType Purchase_New()
    {
        _type = purchase_new;
        Send_Purchase();
    }

    public PurchaseType Purchase_Cancel()
    {
        _type = purchase_cancel;
        Send_Purchase();
    }
}

有两种类型,ChangeType和PurchaseType

这些是从NarcoticsResult继承的。

我认为想要使用此类的人会这样使用。

// this class can only be used when someone wants to use change function 
var logic = SendLogic<ChangeType >();
logic.Change_New();
logic.Change_Cancel();

这是一个问题。

我想强迫此类仅按我的想法使用。

我的意思是,我想防止它像这样使用。

var logic = SendLogic<ChangeType>();
logic.Change_New(); // OK
logic.Purchase_New(); // You should make this class like SendLogic<PurchaseType>()

我想我添加了一些代码来检查每个函数中的T类型。

您如何看待我的想法。我认为有更好的解决方法

请告诉我更好的方法

谢谢。

2 个答案:

答案 0 :(得分:0)

谢谢您的评论

我将其分为以下两个部分

public class ChangeSendLogic : SendLogic<ChangeType>, IChangeLogic
public class PurchaseSendLogic : SendLogic<PurchaseType>, IPurchaseLogic

我也划分了界面

 public interface IChangeLogic
 {
     ChangeType Change_New();
     ChangeType Change_Cancel();
 }

 public interface IPurchaseLogic
 {
     PurchaseType Purchase_New();
     PurchaseType Purchase_Cancel();  
 }

然后我将SendLogic<T>类做成了抽象类。

这是因为我想让想要使用该类的人使用从该类继承的类,而无需直接访问它。

谢谢您的评论。我有个好主意。

答案 1 :(得分:0)

就我个人而言,在这种情况下,您不需要通用类。您需要的是抽象基类或接口。我个人喜欢如下界面方法:

public interface ISendLogic {
    void New();
    void Cancel();
}

因此,现在您有了一项合同,该合同将迫使您的代码使用者仅使用NewCancel方法。

下一步,您可以实现针对特定实现的发送逻辑接口:

public class ChangeSendLogic : ISendLogic {
    private eReportType _type;

    public ChangeSendLogic(
       /*you can put the necessary parameters in the constructor
         and keep it as private fields in the object*/
    ) 
    {

    }

    private bool Send_Change()
    {
        // Send to server by xml file
    }

    public void New() 
    {
        _type = change_new;
        Send_Change();
    }

    public void Cancel() 
    {
        _type = change_cancel;
        Send_Change();  
    }
}

public class PurchaseSendLogic : ISendLogic {
    private eReportType _type;

    public PurchaseSendLogic(
       /*you can put the necessary parameters in the constructor
         and keep it as private fields in the object*/
    ) 
    {

    }
    private bool Send_Purchase()
    {
        // Send to server by xml file
    }

    public void New() 
    {
        _type = change_new;
        Send_Purchase();
    }

    public void Cancel() 
    {
        _type = change_cancel;
        Send_Purchase();  
    }
}

从这里您可以看到这两个类很好地处理了每种类型的实现。您可以认为这是single responsibility principle的实现。因此,如果您有另一种类型,则只需添加该接口的另一种实现,而不用更新现有的类。

如果要隐藏这些对象的创建,则在下一部分中,您可以介绍一种工厂或选择器,如下所示:

public enum SendLogicType {
    Change,
    Purchase
}

public static SendLogicSelector {
    public static ISendLogic GetSendLogic(SendLogicType type) 
    {
         switch(type)
         {
             case SendLogicType.Change:
                  return new ChangeSendLogic();
             case SendLogicType.Purchase:
                  return new PurchaseSendLogic();
         }
    }
}

这是使用代码的方式:

ISendLogic sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Change);
sendLogic.New(); // change new logic executed
sendLogic.Cancel(); // change cancel logic executed

sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Purchase);
sendLogic.New(); // purchase new logic executed
sendLogic.Cancel(); // purchase cancel logic executed

希望您能了解我的方法。祝好运! :)