在接口中实现接口属性?

8
我有一个代码库,我想同时用于ASP.NET MVC和WPF/MVVM前端。业务对象实现为接口,业务逻辑使用这些接口传递数据。
假设我在接口上有一个实现IEnumerable的属性。是否可能使不同版本的该接口使用不同的IEnumerable实现?以下是我尝试实现的例子:
class Reporting
{
    public bool RunReport(IReportParams Params);
}

interface IReportParams
{
    IEnumerable<Guid> SelectedItems { get; }
    IEnumerable<StatusEnum> SelectedStatuses { get; }
}

class MvcReportParams : IReportParams
{
    public List<Guid> SelectedItems { get; set; }
    public List<StatusEnum> SelectedStatuses { get; set; }
}

class WpfReportParams : IReportParams
{
    public ObservableCollection<Guid> SelectedItems { get; set; }
    public ObservableCollection<StatusEnum> SelectedStatuses { get; set; }
}

这能做到吗?

编辑:我应该也问“怎么做”,因为当我尝试这样做时,我会遇到类似于以下错误:

“MvcReportParams”未实现接口成员“IReportParams.SelectedStatuses”。“MvcReportParams.SelectedStatuses”无法实现“IReportParams.SelectedStatuses”,因为它没有匹配的返回类型“System.Collections.Generic.IEnumerable”。

ObservableCollection和List都绝对实现了IEnumerable,所以这对我来说似乎不合理。

最后编辑

好吧,有人回答了我的问题,但他们出于某种原因删除了它,所以我无法将其标记为解决方案。这是我最终做的事情:

interface IReportParams
{
    IEnumerable<Guid> SelectedItems { get; }
    IEnumerable<StatusEnum> SelectedStatuses { get; }
}

class MvcReportParams : IReportParams
{
    // Properties that the modelbinder dims and sets up
    public List<Guid> SelectedItems { get; set; }
    public List<StatusEnum> SelectedStatuses { get; set; }

    // Explicityly implement my interface
    IEnumerable<Guid> IReportParams.SelectedItems
    {
        get { return SelectedItems; }
    }

    IEnumerable<StatusEnum> IReportParams.SelectedStatuses
    {
        get { return SelectedStatuses; }
    }
}

class WpfReportParams : IReportParams
{
    // Properties that my view dims and modifies
    public ObservableCollection<Guid> SelectedItems { get; set; }
    public ObservableCollection<StatusEnum> SelectedStatuses { get; set; }

    // Explicityly implement my interface
    IEnumerable<Guid> IReportParams.SelectedItems
    {
        get { return SelectedItems; }
    }

    IEnumerable<StatusEnum> IReportParams.SelectedStatuses
    {
        get { return SelectedStatuses; }
    }
}

虽然需要编写更多的样板代码,但我仍然更喜欢更加明确。


1
此外,你直接尝试一下会比写一个问题更快。 - Sam Axe
@Boo 刚想说这个 Boo。也许这更多是关于理解它为什么能(或不能)工作,而不是它是否能工作,因为无论回答有多快,编译器都会比堆栈溢出更快地告诉你 :) - dreza
更新了问题描述以使其更加清晰。 - Stevoman
@Baconcheese 也许你会遇到错误,因为在你的接口中没有为 SelectedItemsSelectedStatuses 设置器。 - Kamyar
1
@Kamyar 在接口中未声明的 setter 完全没有问题。 - Paul Phillips
所以针对我上面有点误导性的评论,你需要像其他人下面描述的那样修改你的实现。 - Sam Axe
2个回答

9

我会采用只读属性来实现这个功能。对于客户端而言,向现有集合中添加/删除/更新条目比完全替换集合更好的做法。

interface IReportParams
{
    IEnumerable<Guid> SelectedItems { get; }
    IEnumerable<StatusEnum> SelectedStatuses { get; }
}

class MvcReportParams : IReportParams
{
    public MvcReportParams()
    {
        SelectedItems = new Collection<Guid>();
        SelectedStatuses = new Collection<StatusEnum>();
    }

    public IEnumerable<Guid> SelectedItems { get; private set; }
    public IEnumerable<StatusEnum> SelectedStatuses { get; private set; }
}

class WpfReportParams : IReportParams
{
    public WpfReportParams()
    {
        SelectedItems = new ObservableCollection<Guid>();
        SelectedStatuses = new ObservableCollection<StatusEnum>();
    }

    public IEnumerable<Guid> SelectedItems { get; private set; }
    public IEnumerable<StatusEnum> SelectedStatuses { get; private set; }
}

0

遇到了相同的问题。发现正在实现的接口也需要是公共的。

public interface IReportParams
{
    IEnumerable<Guid> SelectedItems { get; }
    IEnumerable<StatusEnum> SelectedStatuses { get; }
}

这应该解决问题。

谢谢, Subhajit


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接