Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing interface properties in interfaces?

I have a code base I want to use for both an ASP.NET MVC and a WPF/MVVM front end. The business objects are implement as interfaces and the business logic uses these interfaces for passing data.

Say I have a property on my interface that implements IEnumerable. Is it possible to have different versions of this interface use different implementations of IEnumerable? An example of what I am trying to accomplish:

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

Can this be done?

Edit: I should also have asked "how", because when I try this, I get errors similar to this:

'MvcReportParams' does not implement interface member 'IReportParams.SelectedStatuses'. 'MvcReportParams.SelectedStatuses' cannot implement 'IReportParams.SelectedStatuses' because it does not have the matching return type of 'System.Collections.Generic.IEnumerable'

ObservableCollection and List both absolutely implement IEnumerable, and so this does not seem to make sense to me.

Last Edit

Well, someone posted the answer, but they deleted it for some reason, so I can't mark it as the solution. Here's what I ended up doing:

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

It's more lines of boilerplate code to write, but I like being more explicit anyways.

like image 693
Stevoman Avatar asked Mar 23 '12 19:03

Stevoman


People also ask

Can we add properties in interface?

An interface can contain declarations of methods, properties, indexers, and events. However, it cannot contain fields, auto-implemented properties. The following interface declares some basic functionalities for the file operations. You cannot apply access modifiers to interface members.

How do you initialize an interface property?

You just specify that there is a property with a getter and a setter, whatever they will do. In the class, you actually implement them. The shortest way to do this is using this { get; set; } syntax. The compiler will create a field and generate the getter and setter implementation for it.

CAN interface have properties Java?

Interface attributes are by default public , static and final. An interface cannot contain a constructor (as it cannot be used to create objects)

CAN interface have fields in C#?

An interface may not declare instance data such as fields, auto-implemented properties, or property-like events. By using interfaces, you can, for example, include behavior from multiple sources in a class. That capability is important in C# because the language doesn't support multiple inheritance of classes.


1 Answers

I would probably implement this with read-only properties. It better pratice for the client to add/remove/update items in an existing collection rather than replace the collection altogether.

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; }
}
like image 108
Phil Avatar answered Nov 02 '22 04:11

Phil