简体   繁体   中英

Generic interface implementation confusion

I'm getting myself in a bit of a mess regarding interface implementations, all my attempted 'fixes' seem to make the whole solution more complex and broken. I'm sure there is a simple answer, but I can't quite see it at the moment!

I have these two interfaces (the second is used in a list of the first):

public interface IUserDefinedListEditViewModel<T> where T : IUserDefinedListEntryEditViewModel<IBaseUserDefinedListModel>
{
    string TypeName { get; set; }
    IList<T> UserDefinedListEntries { get; set; }
}

public interface IUserDefinedListEntryEditViewModel<T> where T : IBaseUserDefinedListModel
{
    string Display { get; set; }
    T UserDefinedListEntry { get; set; }
}

I have a third interface which is implemented by several different classes:

public interface IBaseUserDefinedListModel
{
    Guid Id { get; set; }
    string Name { get; set; }
    bool IsSystem { get; set; }
}

Below is my (incorrect) implementation attempt:

public class APEditViewModel : IUserDefinedListEditViewModel<APEntryEditViewModel>
{
    public string TypeName { get; set; }
    public IList<APEntryEditViewModel> UserDefinedListEntries { get; set; } = new List<APEntryEditViewModel>();
}

public class APEntryEditViewModel : IUserDefinedListEntryEditViewModel<APModel>
{
    public string Display { get; set; }
    public APModel UserDefinedListEntry { get; set; }
}

public class BaseUserDefinedListModel : IBaseUserDefinedListModel
{
    public Guid Id { get; set; }
    [Required(ErrorMessage = "The Name field is required.")]
    public string Name { get; set; }
    public bool IsSystem { get; set; }
}

public class APModel : BaseUserDefinedListModel
{
    public string NewValue { get; set; }
}

The main error I'm getting at the moment is in the APEditViewModel, here is the (cut down) error:

The type 'APEntryEditViewModel' cannot be used as type parameter 'T' in the
generic type or method 'IUserDefinedListEditViewModel<T>'. There is no 
implicit reference conversion from 'APEntryEditViewModel' to 
'IUserDefinedListEntryEditViewModel<IBaseUserDefinedListModel>'.

I'm not sure whether I need this level of generic interfaces, but from my research and experiments, I believe I do. I'm just not quite getting there and I'm thinking that the IUserDefinedListEditViewModel interface needing a type in the type interface ( IUserDefinedListEntryEditViewModel ) seems wrong.

Sorry that I'm not making myself that clear, it's quite tricky to explain because I'm not sure where I'm going wrong, so any questions I'll try and answer/update my question.

Change your IUserDefinedListEditViewModel interface to:

public interface IUserDefinedListEditViewModel<T1,T2> 
           where T1 : IUserDefinedListEntryEditViewModel<T2> 
           where T2 : IBaseUserDefinedListModel

After that, and update the implementation in APEditViewModel :

public class APEditViewModel : IUserDefinedListEditViewModel<APEntryEditViewModel, APModel>

The error indicates that with the generic constraint

where T : IUserDefinedListEntryEditViewModel<IBaseUserDefinedListModel>

only IUserDefinedListEntryEditViewModel<IBaseUserDefinedListModel> and types which implement this interface will be accepted as T . If you want any IBaseUserDefinedListModel to be accepted in the type parameter of T , you need to make it generic as well.

You need to give us the whole business scenario for expecting the right design suggestions.

As of above examples the issue is: Your defined interface::

interface IUserDefinedListEditViewModel<T> where T : IUserDefinedListEntryEditViewModel<IBaseUserDefinedListModel>

But while calling you are passing APEntryEditViewModel as Interface specific type. Which is wrong with OOPS.

To successfully compile this your

APEntryEditViewModel must be an implimentation of IUserDefinedListEntryEditViewModel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM