I am creating a chat app. In the chat, users can send three types of messages: images, files, and text messages. I am trying to create an interface called IMessege
that contain 3 class properties:
interface IMessege
{
object content { get; }
User sender { get; }
DateTime sent { get; }
}
Then I want to implement the interface in 3 classes: FileMessege
, ImageMessege
and StringMessege
. I want them all to have User sender
and DateTime sent
, but the content
I want to be from type string
at StringMessege
, from type file
at FileMessege
etc...
I did not think this is going to be a problem since all these classes inherit from object
, but apparently it is.
how can I do it?
(I've changed the names in both options to be idiomatic C#.)
Option 1: make IMessage generic in the type of content
interface IMessage<TContent>
{
TContent Content { get; }
User Sender { get; }
DateTime Sent { get; }
}
public class FileMessage : IMessage<File>
{
...
}
public class StringMessage : IMessage<string>
{
...
}
// etc
Advantage: always strongly typed
Disadvantage: you now can't have (say) a List<IMessage>
. You could mitigate this by separating out the non-generic and generic parts:
interface IMessage
{
User Sender { get; }
DateTime Sent { get; }
}
interface IMessage<TContent> : IMessage
{
TContent Content { get; }
}
Option 2: use explicit interface implementation
interface IMessage
{
object Content { get; }
User Sender { get; }
DateTime Sent { get; }
}
public class FileMessage : IMessage
{
// Explicit interface implementation of the object-typed Content property
object IMessage.Content => Content;
// Regular strongly-typed property for Content
public File Content { get; }
// Other interface properties
}
// etc
Advantage: No need for generics
Disadvantage: Weakly-typed access to content when using the interface, and slightly more complicated code.