I have a couple of interfaces like this:
public interface IAppointment<TUser> where TUser : IUser
{
string TeamName { get; set; }
TUser Host { get; set; }
string HostNameForGuest { get; }
bool HostNameVisible { get; set; }
}
and
public interface IUser
{
string FirstName { get; set; }
string LastName { get; set; }
}
The use of a generic for the IAppointment
interface is because one of the classes where I'm implementing it is auto-generated by Entity Framework and I can't change the return type of the Host
property from User
(the name of the database entity it describes) to IUser
. This implementation is shown below. The other properties specified in the interface are already present in the EF-generated partial class of the same name.
public partial class Appointment : IAppointment<User>
{
public string HostNameForGuest
{
get
{
return AppointmentHelper.HostNameForGuest(this);
}
}
}
As you can see, I'm trying to get the value for the HostNameForGuest
property from a function, the reason being that I want to reuse the logic for deriving the value in multiple other classes which implement the same interface. The function looks like this:
public static string HostNameForGuest(IAppointment<IUser> appointment)
{
return appointment.HostNameVisible ? $"{appointment.Host.FirstName} appointment.Host.LastName}" : appointment.TeamName;
}
The problem I have is that the above code throws an IntelliSense error for the line
return AppointmentHelper.HostNameForGuest(this);
Underlining this
and saying:
Argument 1: cannot convert from 'AppointmentBooking.DAL.Appointment' to 'AppointmentBooking.Global.Interfaces.IAppointment<AppointmentBooking.Global.Interfaces.IUser>'
I understand the error but I don't know how to fix it. I realise this is just exposing a shortcoming in my knowledge of generics, which are not something I've used often, and it's probably just a case of expressing the parameters correctly, but no combination I've tried has worked so far. I've tried modifying the line to:
return AppointmentHelper.HostName(this<User>);
and
return AppointmentHelper.HostName(this<IUser>);
both of which yield the error
'User' is a type, which is not valid in the given context
('User'
is 'IUser'
in the error message for the second example, obviously).
So what's the correct way to pass the class that implements IAppointment<IUser>
as a parameter to the function which accepts the interface type as a parameter?
EDIT
The questions which have been suggested as duplicates for this all seem to boil down to people trying to convert a derived class to its base class. I don't think that's what I'm doing, though I'm quite prepared to be told I'm wrong.
For a start, I'm not inheriting a class, I'm implementing an interface.
Secondly, I don't have any complaints from the compiler when I take out the IUser
interface. This doesn't throw the error:
public interface IAppointment
{
string TeamName { get; set; }
string HostNameForGuest { get; }
bool HostNameVisible { get; set; }
}
public partial class Appointment : IAppointment
{
public string HostNameForGuest
{
get
{
return AppointmentHelper.HostNameForGuest(this);
}
}
}
public static string HostNameForGuest(IAppointment appointment)
{
return appointment.HostNameVisible ? $"{appointment.Host.FirstName} appointment.Host.LastName}" : appointment.TeamName;
}
If the problem was me trying to convert the "derived" Appointment
class (I don't know if "derived" is the right term for a class that implements an interface or if it refers specifically to a class that inherits another class) to the "base" class IAppointment
(again, it's an interface, not a base class) then I'd still expect to get the same error. Wouldn't I..?