4

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.

5
  • An interface should not be implemented by classes. It is a method for inserting and extracting data from a class. I think you want to make IBaseUserDefinedListModel a class instead of an interface. Commented Sep 4, 2018 at 11:21
  • @jdweng An interface should not be implemented by classes? You may want to rephrase that Commented Sep 4, 2018 at 11:23
  • "An interface should not be implemented by classes." that sounds rather confusing. Do you care to elaborate on this one? Commented Sep 4, 2018 at 11:23
  • @CamiloTerevinto "An interface can only be implemented by a class." An interface can also be implemented by structs. Commented Sep 4, 2018 at 11:24
  • @ikkentim I use structs so little lately that I forget about that, thanks though Commented Sep 4, 2018 at 11:25

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked exactly how I wanted it to, I knew I was close... ish! Just one small thing, the comma between the where on the first interface type isn't required.
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.