Как заставить мои классы использовать, как я думал с T - PullRequest
0 голосов
/ 07 декабря 2018

Я создал класс с 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 голосов
/ 07 декабря 2018

Лично я не думаю, что вам нужен универсальный класс в этом случае.Вам нужен либо абстрактный базовый класс, либо интерфейс.Мне лично нравится интерфейсный подход, как показано ниже:

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

Так что теперь у вас есть контракт, который заставит потребителя вашего кода использовать только методы New или Cancel.

Следующий шаг, который вы можете реализовать, - это логический интерфейс отправки для вашей конкретной реализации:

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();  
    }
}

Здесь вы можете видеть, что эти два класса прекрасно обрабатывают реализацию для каждого типа.Вы можете думать, что это как реализация принципа единой ответственности .Поэтому, если у вас есть еще один тип, вы можете просто добавить еще одну реализацию этого интерфейса вместо обновления существующих классов.

Если вы хотите скрыть создание этих объектов, в следующей части вы можете представитьвид фабрики или селектора, как показано ниже:

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

Надеюсь, вы можете понять мой подход.Удачи!:)

0 голосов
/ 07 декабря 2018

Спасибо за ваш комментарий

Я разделил его на две части, как показано ниже

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> от класса к абстрактному классу.

Это потому, что я хочу заставить человека, который хочет использовать этот класс, использовать класс, который наследует от этого класса, без прямого доступа к нему.

Спасибоза ваш комментарий.У меня есть хорошая идея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...