gpt4 book ai didi

C# - 通过相同的方法传递不同类型的对象

转载 作者:太空宇宙 更新时间:2023-11-03 17:10:13 25 4
gpt4 key购买 nike

原始问题

所以我有这 3 个对象...

public class obj1
{
public int Id { get; set; }
public string Name { get; set; }
}

public class obj2
{
public int AccNum { get; set; }
public string Name { get; set; }
}

public class obj3
{
public string Email { get; set; }
public string Phone { get; set; }
}

...和一个应该接收其中之一的方法,在评估对象类型之后,程序应该决定调用哪个函数。

我尝试过使用泛型,但它没有像我预期的那样工作。到目前为止,这就是我所拥有的...

    public class NotificationHelper: INotificationHelper
{

public bool SendNotification<TNotInfo>(TNotInfo obj) where TNotInfo : class
{
if (contract.GetType() == typeof (obj1))
{
var sender = new SendSMS();
return sender.Send(obj);
}
if (contract.GetType() == typeof(obj2))
{
var sender = new SendPush();
return sender.Send(obj);
}
else
{
var sender = new SendEmail();
return sender.Send(obj);
}
}
}

但我收到错误“无法从 TNotInfo 转换为 Models.obj1”。有什么办法可以克服这个问题吗?或者我必须改变我的逻辑?

感谢任何帮助,提前致谢。

*编辑

using System;

namespace EmailNotifications
{

public interface IEmailNotification
{
void SendEmailNotification();
}

public class EmailNotificationA : IEmailNotification
{

public void SendEmailNotification(Contract1 a)
{
Console.WriteLine($"Sending EmailNotificationA ({a})");
}
}

public class EmailNotificationB : IEmailNotification
{
public void SendEmailNotification(Contract2 b)
{
Console.WriteLine($"Sending EmailNotificationB ({b})");
}
}

public class EmailNotificationC : IEmailNotification
{

public void SendEmailNotification(Contrac3 c)
{
Console.WriteLine($"Sending EmailNotificationC ({c})");
}
}

public class EmailNotificationService
{
private readonly IEmailNotification _emailNotification;

public EmailNotificationService(IEmailNotification emailNotification)
{
this._emailNotification = emailNotification;
}

public void ServiceHelper()
{
_emailNotification.SendEmailNotification();
}
}
}

以上解决方案是我试图通过应用策略设计模式实现的。但是我无法让我的接口(interface)方法接收不同的对象,这是必需的,因为每个通知都有自己的实现。从上面的无工作示例中可以看出,我有 3 个相同方法的不同实现,它们都接收不同的对象。知道如何使这个逻辑起作用吗?

最佳答案

这就是界面设计要做的事情。首先,定义一个公共(public)接口(interface):

public interface INotifier
{
bool Notify();
}

其次,在您的 objX 类中实现它:

public class obj1 : INotifier
{
public int Id { get; set; }
public string Name { get; set; }

public bool Notify()
{
var sender = new SendSMS();
return sender.Send(this);
}
}

public class obj2 : INotifier
{
public int AccNum { get; set; }
public string Name { get; set; }

public bool Notify()
{
var sender = new SendPush();
return sender.Send(this);
}
}

public class obj3 : INotifier
{
public string Email { get; set; }
public string Phone { get; set; }

public bool Notify()
{
var sender = new SendEmail();
return sender.Send(this);
}
}

最后,更改您的通知方法以接受接口(interface)类型作为参数:

public class NotificationHelper : INotificationHelper
{
public bool SendNotification(INotifier obj)
{
return obj.Notify();
}
}

编辑(2019):

我正在重新审视这个答案,因为它似乎获得了相当大的知名度。 OP 可能早已继续前进,但对于可能偶然发现这个答案的其他人来说,这是另一种解决方案。

我仍然相信接口(interface)是可行的方法。但是,上面建议的接口(interface)非常通用,最终并不是非常有用。它还会遇到一些 DRY 违规行为,因为正如 Fabio 在评论中所说,如果两个 objX 类以相同的方式实现通知,这种方法会强制您在它们之间复制代码。

不是一个全局接口(interface),而是每个特定通知任务的接口(interface),即 ISMSNotificationIPushNotificationIEmailNotification。然后,您可以使用混合模式为每个接口(interface)实例提供发送方法的默认实现:

interface ISmsNotifier
{
int SmsId { get; }
string SmsName { get; }
}

static class ISmsNotifierExtensions
{
public static bool NotifySms(this ISmsNotifier obj)
{
var sender = new SendSMS();
return sender.Send(obj);
}
}

// ---------------------------------------------

interface IPushNotifier
{
int PushAccNum { get; }
string PushName { get; }
}

static class IPushNotifierExtensions
{
public static bool NotifyPush(this IPushNotifier obj)
{
var sender = new SendEmail();
return sender.Send(obj);
}
}

// ---------------------------------------------

interface IEmailNotifier
{
string EmailAddress { get; }
string EmailPhone { get; }
}

static class IEmailNotifierExtensions
{
public static bool NotifyEmail(this IEmailNotifier obj)
{
var sender = new SendEmail();
return sender.Send(obj);
}
}

然后您可以像这样在 objX 类中实现它:

public class obj1 : INotifier, ISmsNotifier 
{
public int SmsId { get; set; }
public string SmsName { get; set; }

public bool Notify() => this.NotifySms();
}

public class obj2 : INotifier, IPushNotifier
{
public int PushAccNum { get; set; }
public string PushName { get; set; }

public bool Notify() => this.NotifyPush();
}

public class obj3 : INotifier, IEmailNotifier
{
public string EmailAddress { get; set; }
public string EmailPhone { get; set; }

public bool Notify() => this.NotifyEmail();
}

请注意,使用这种方法不仅可以轻松支持使用相同通知系统的对象,还可以支持具有多个 通知系统的对象:

public class obj4 : INotifier, IEmailNotifier, IPushNotifier
{
public int PushAccNum { get; set; }
public string PushName { get; set; }
public string EmailAddress { get; set; }
public string EmailPhone { get; set; }

public bool Notify() => this.NotifyEmail() && this.NotifyPush();
}

您可能会注意到这种方法使 NotificationHelper 过时,因为不再需要通过处理步骤传递对象来确定通过哪个通知系统处理对象。这是真的,也许是正确的,因为对象应该完全能够自己决定(取决于你处理这个问题的心态)。但是,NotificationHelper 可能仍有其用途,例如,如果您想要预处理发送到通知服务的信息,或者如果您想要一个公共(public)入口点来帮助进行模拟和测试。

C# 8 注意:

C# 8 的一项提议功能是能够在接口(interface)定义本身内为接口(interface)提供方法的默认实现。当(如果)发生这种情况时,您不再需要使用混合模式,可以直接在接口(interface)中定义默认方法实现。该功能尚未最终确定,但它可能看起来像这样:

interface ISmsNotifier 
{
int SmsId { get; }
string SmsName { get; }

public bool NotifySms()
{
var sender = new SendSMS();
return sender.Send(this);
}
}

// ---------------------------------------------

interface IPushNotifier
{
int PushAccNum { get; }
string PushName { get; }

public bool NotifyPush()
{
var sender = new SendEmail();
return sender.Send(this);
}
}

// ---------------------------------------------

interface IEmailNotifier
{
string EmailAddress { get; }
string EmailPhone { get; }

public bool NotifyEmail()
{
var sender = new SendEmail();
return sender.Send(this);
}
}

关于C# - 通过相同的方法传递不同类型的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43183133/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com