在继承的类中使用不同类型的更好方法

时间:2018-07-24 13:34:47

标签: c# inheritance return-type

我在使用N个提供程序发送SMS消息的Web服务中工作。每个提供者都在其自己的Web服务上以不同的格式接收消息。

为了在我的Web服务中创建模式,我创建了一个抽象类,其中包含许多要为每个提供程序实现的方法。

某些方法需要接收一个可以具有不同类型的对象,具体取决于继承该对象的子类(提供者)。这些方法之一返回的对象可以是至少两种不同的类型。

我通过“ object”关键字实现了此目的,该关键字使我可以传递或返回任何对象:

public abstract class Provider {
    protected HttpClient _Client;
    protected SMSManagerAPIContext _Context;

    public abstract DeliveryResponse SendSMS(object Sms);
    protected abstract DeliveryResponse ParseResponse(HttpResponseMessage Response);
    public abstract object PrepareMessage(SMS Sms);
    protected abstract void SaveResponse(object Sms, HttpResponseMessage Response);
}

Sms方法中接收到的对象SendSMSPrepareMessage方法的返回。问题是PrepareMessage可能返回不同类型的对象。

(例如,我的一个提供程序接受了发送一条或多条消息的请求,但是每个对象的对象都不同。然后,​​我在PrepareMessage方法中返回正确的对象,而在{{1 }}方法将其作为JSON对象发送给提供程序。)

它可以工作,但是在开发过程中会在子类中引起一些转换问题,我想知道是否有更好的方法可以做到这一点。 我已经阅读了有关此问题的一些信息:

C# Return Different Types?

Generic method that can return different types

我认为使用泛型的重载方法会更好,但是我没有C#的经验。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我认为您是正确的,听起来确实是使用泛型的好地方,也许像这样,“ T”(按惯例称为t)就是您使用的类型。

public abstract class Provider<T>
{
    protected HttpClient _Client;
    protected SMSManagerAPIContext _Context;

    public abstract DeliveryResponse SendSMS(T Sms);
    protected abstract DeliveryResponse ParseResponse(HttpResponseMessage Response);
    public abstract T PrepareMessage(SMS Sms);
    protected abstract void SaveResponse(object Sms, HttpResponseMessage Response);
}


public class SMS {
    public string Message { get; set; }
}

public class SMSManagerAPIContext{}


public class DeliveryResponse { }


public class PremiumSMS
{
    public double Cost { get; set; }
    public string Message { get; set; }

}


public class PremiumSmsProvider : Provider<PremiumSMS>
{
    public const double Cost = 3.99;

    public override PremiumSMS PrepareMessage(SMS Sms)
    {
        return new PremiumSMS {
            Message = Sms.Message, 
            Cost = Cost
        };
    }

    public override DeliveryResponse SendSMS(PremiumSMS Sms)
    {
        throw new NotImplementedException();
    }

    protected override DeliveryResponse ParseResponse(HttpResponseMessage Response)
    {
        throw new NotImplementedException();
    }

    protected override void SaveResponse(object Sms, HttpResponseMessage Response)
    {
        throw new NotImplementedException();
    }
}

public class FreeSMS
{

    public string Message { get; set; }

}



public class FreeSmsProvider : Provider<FreeSMS>
{
    public override FreeSMS PrepareMessage(SMS Sms)
    {
        return new FreeSMS{
            Message = Sms.Message
        };
    }

    public override DeliveryResponse SendSMS(FreeSMS Sms)
    {
        throw new NotImplementedException();
    }

    protected override DeliveryResponse ParseResponse(HttpResponseMessage Response)
    {
        throw new NotImplementedException();
    }

    protected override void SaveResponse(object Sms, HttpResponseMessage Response)
    {
        throw new NotImplementedException();
    }
}

有关泛型类的更多信息:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-classes

答案 1 :(得分:1)

使用工厂。使用此代码的代码可能只关心将字符串消息发送给某个电话号码,并获取该消息是否成功,如果失败则返回错误消息。

创建消息本身以遵守不同的提供者/实现应该只是在一个黑框中。不同的提供程序将具有不同的构造函数。

public interface ISmsProvider 
{
    (bool, string) SendMessage(string number, string message);
}

public class SampleSmsProvider1 : ISmsProvider
{
    public SampleSmsProvider1(string userKey, string passKey) 
    {
        // initialize           
    }

    public (bool, string) SendMessage(string number, string message) 
    {
        // send the message (using a provider implementation from NuGet perhaps)

        // return success/fail and error message, if applicable
        return (true, string.Empty);
    }
}

public class SmsFactory
{
    public ISmsProvider GetProvider() 
    {
        // Initialize and return one of the ISmsProvider implementations, depending on (I guess) the configuration
    }
}