首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >通用接口作为方法参数和查看字段

通用接口作为方法参数和查看字段
EN

Stack Overflow用户
提问于 2019-07-14 23:38:02
回答 2查看 0关注 0票数 0

这可能是我天真的表现,但无论如何......

我有一个通用接口,它定义了一组跨实现的标准方法(以不同方式实现)。

我将接口作为参数传递给方法,该方法负责持久化到数据库。例如,我有一些称为bug,事件等的实现,它们是从通用接口(称为IEntry)定义的。这些概念实现也使用IEnumerable

由于错误与事件不同,因此存在不同的字段。当我将接口作为参数传递给方法时,有没有办法推断出类型?因此,如果我传入Bug对象,我可以使用其字段,这些字段与Incident中的字段不同。这些字段对于数据库的持久性非常有用。我假设没有,因为没有办法知道传递的类型(显然),但我知道这里的人有更多的智慧。在这种情况下,有更好的做事方式吗?由于相似性,我想坚持接口。

编辑:我想另一种方法是使用一些流控制来动态生成sql语句,然后将其作为参数传递。

谢谢

EN

回答 2

Stack Overflow用户

发布于 2019-07-15 08:06:12

关于传递对象和接口的事情是,你真的不应该关心实际的类型,只要它继承自/实现你感兴趣的特定基类/接口。

因此,在该方法中构建逻辑以确定它是一个错误,然后访问仅针对错误的内容,这基本上不是OOP方式,尽管它可能是您特定情况下的“最佳”方式。

但是,我会建议反对它,而是尝试使用多态来构建一个适当的OOP方法来处理差异,而不是将其作为特殊情况构建到方法中。

你提到持久性,这个方法负责将数据存储在某个地方吗?也许您可以将收集信息的部分与存储信息的部分分开,这样您就可以要求对象本身为您提供所有相关信息,这些信息可能因类而异。

票数 0
EN

Stack Overflow用户

发布于 2019-07-15 09:26:16

糟糕的设计(我认为在问题中描述):

代码语言:javascript
复制
public interface IEntry
{
    string Description { get; set; }
}
public class Bug : IEntry
{
    public int ID { get; set; }
    public string Description { get; set; }
    public string UserName { get; set; }
}
public class Incident : IEntry
{
    public Guid ID { get; set; }
    public string Description { get; set; }
}

public class Persister
{
    public void Save(IEnumerable<IEntry> values)
    {
        foreach (IEntry value in values) { Save(value); }
    }

    public void Save(IEntry value)
    {
        if (value is Bug) { /* Bug save logic */ }
        else if (value is Incident) { /* Incident save logic */ }
    }
}

改进的设计(智能实体方法):

代码语言:javascript
复制
public interface IEntry
{
    string Description { get; set; }
    void Save(IPersister gateway);
}

public class Bug : IEntry
{
    public int ID { get; set; }
    public string Description { get; set; }
    public string UserName { get; set; }

    public void Save(IPersister gateway)
    {
        gateway.SaveBug(this);
    }
}

public class Incident : IEntry
{
    public Guid ID { get; set; }
    public string Description { get; set; }

    public void Save(IPersister gateway)
    {
        gateway.SaveIncident(this);
    }
}

public interface IPersister
{
    void SaveBug(Bug value);
    void SaveIncident(Incident value);
}

public class Persister : IPersister
{
    public void Save(IEnumerable<IEntry> values)
    {
        foreach (IEntry value in values) { Save(value); }
    }

    public void Save(IEntry value)
    {
        value.Save(this);
    }

    public void SaveBug(Bug value)
    {
        // Bug save logic
    }

    public void SaveIncident(Incident value)
    {
        // Incident save logic
    }
}

改进的设计仅满足需要更改Persister.Save(IEntry)的需要。我只想展示使代码不那么脆弱的第一步。在现实和生产代码中,您可能希望拥有BugPersister和IncidentPersister类,以符合单一责任原则

希望这个以代码为中心的例子是一个帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100001298

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档