C# 如何创建接口基属性,然后使用派生属性实现?

C# 如何创建接口基属性,然后使用派生属性实现?,c#,inheritance,interface,polymorphism,class-properties,C#,Inheritance,Interface,Polymorphism,Class Properties,我正在创建一个聊天应用程序。在聊天中,用户可以发送三种类型的消息:图像、文件和文本消息。我正在尝试创建一个名为IMessage的接口,该接口包含3个类属性: 接口IMessage { 对象内容{get;} 用户发送方{get;} 已发送日期时间{get;} } 然后我想实现3个类的接口:FileMessege、ImageMessege和StringMessege。我希望他们都有用户发送人和日期时间发送,但我希望的内容是从类型字符串在StringMessege,从类型文件在FileMessege等

我正在创建一个聊天应用程序。在聊天中,用户可以发送三种类型的消息:图像、文件和文本消息。我正在尝试创建一个名为IMessage的接口,该接口包含3个类属性:

接口IMessage { 对象内容{get;} 用户发送方{get;} 已发送日期时间{get;} } 然后我想实现3个类的接口:FileMessege、ImageMessege和StringMessege。我希望他们都有用户发送人和日期时间发送,但我希望的内容是从类型字符串在StringMessege,从类型文件在FileMessege等

我不认为这会是一个问题,因为所有这些类都继承自object,但显然是这样


我该怎么做呢?

您可以使用通用接口。例如

public interface IMessage<T>
{
    T content { get; }
    string sender { get; }
    DateTime sent { get; }
}
现在您可以将类定义为

public class StringMessage:IMessage<string>
{
    public string content { get; }
    public string sender { get; }
    public DateTime sent { get; }
}

public class FileMessage:IMessage<FileInfo>
{
    public FileInfo content { get; }
    public string sender { get; }
    public DateTime sent { get; }
}

public class ImageMessage:IMessage<Image>
{
    public Image content { get; }
    public string sender { get; }
    public DateTime sent { get; }
}
但是,您也可以定义一个通用类消息,这取决于类的其他职责。如果类之间的唯一区别是内容的类型,那么您也可以根据您的用例使用以下内容。下面的示例使用单个泛型类实例化基于字符串、图像和文件的不同实例

public class Message<T>:IMessage<T>
{
    public T content { get; }
    public string sender { get; }
    public DateTime sent { get; }
}
现在可以将不同的实例初始化为

var fileMessage = new Message<FileInfo>();
var stringMessage = new Message<String>();
var imageMessage = new Message<Image>();

您可以使用通用接口。例如

public interface IMessage<T>
{
    T content { get; }
    string sender { get; }
    DateTime sent { get; }
}
现在您可以将类定义为

public class StringMessage:IMessage<string>
{
    public string content { get; }
    public string sender { get; }
    public DateTime sent { get; }
}

public class FileMessage:IMessage<FileInfo>
{
    public FileInfo content { get; }
    public string sender { get; }
    public DateTime sent { get; }
}

public class ImageMessage:IMessage<Image>
{
    public Image content { get; }
    public string sender { get; }
    public DateTime sent { get; }
}
但是,您也可以定义一个通用类消息,这取决于类的其他职责。如果类之间的唯一区别是内容的类型,那么您也可以根据您的用例使用以下内容。下面的示例使用单个泛型类实例化基于字符串、图像和文件的不同实例

public class Message<T>:IMessage<T>
{
    public T content { get; }
    public string sender { get; }
    public DateTime sent { get; }
}
现在可以将不同的实例初始化为

var fileMessage = new Message<FileInfo>();
var stringMessage = new Message<String>();
var imageMessage = new Message<Image>();

我已将两个选项中的名称都更改为惯用的C

选项1:使IMessage在内容类型中成为泛型

接口消息 { t内容内容{get;} 用户发送方{get;} 已发送日期时间{get;} } 公共类文件消息:IMessage { ... } 公共类StringMessage:IMessage { ... } //等 优点:总是强类型 缺点:你现在不能说一个列表。您可以通过分离非通用部分和通用部分来缓解这一问题:

接口消息 { 用户发送方{get;} 已发送日期时间{get;} } 接口IMessage:IMessage { t内容内容{get;} } 选项2:使用显式接口实现

接口消息 { 对象内容{get;} 用户发送方{get;} 已发送日期时间{get;} } 公共类文件消息:IMessage { //对象类型内容属性的显式接口实现 对象IMessage.Content=>Content; //内容的正则强类型属性 公共文件内容{get;} //其他接口属性 } //等 优点:不需要泛型
缺点:使用界面时对内容的访问类型较弱,代码稍微复杂一些。

我已将两个选项中的名称都更改为惯用C

选项1:使IMessage在内容类型中成为泛型

接口消息 { t内容内容{get;} 用户发送方{get;} 已发送日期时间{get;} } 公共类文件消息:IMessage { ... } 公共类StringMessage:IMessage { ... } //等 优点:总是强类型 缺点:你现在不能说一个列表。您可以通过分离非通用部分和通用部分来缓解这一问题:

接口消息 { 用户发送方{get;} 已发送日期时间{get;} } 接口IMessage:IMessage { t内容内容{get;} } 选项2:使用显式接口实现

接口消息 { 对象内容{get;} 用户发送方{get;} 已发送日期时间{get;} } 公共类文件消息:IMessage { //对象类型内容属性的显式接口实现 对象IMessage.Content=>Content; //内容的正则强类型属性 公共文件内容{get;} //其他接口属性 } //等 优点:不需要泛型
缺点:使用界面时对内容的访问类型较弱,代码也稍微复杂一些。

听起来你的界面在内容类型上应该是通用的。您可以使用显式接口实现,但使其更通用可能更简洁。我将添加这两个选项作为答案。听起来您的界面在内容类型上应该是通用的。您可以使用显式接口实现,但使其更通用可能更简洁。我将两个选项都添加为答案。@Jon Skeet说得有道理。如果我将接口设置为通用接口,我就不能使用消息列表,那么接口到底有什么意义?@avivgood2在这种情况下,按照Jon的建议拆分接口的通用部分和非通用部分是个好主意
,同时仍然具有强类型的优点content@Jon双向飞碟有道理。如果我将接口设置为泛型,我就不能使用消息列表,那么接口到底有什么意义?@avivgood2在这种情况下,按照Jon的建议拆分接口的泛型和非泛型部分是一个好主意,同时仍然具有强类型内容的优点。对于解决方案1,修复到列表,我可以从IMessage访问内容吗?因为似乎只有sender和sent可以访问。@avivgood2:不,非通用接口根本没有内容。如果您希望能够以弱类型的方式获取任何内容,那么第二个选项可能更好。对于解决方案1“修复列表”,我可以从IMessage访问内容吗?因为似乎只有sender和sent可以访问。@avivgood2:不,非通用接口根本没有内容。如果您希望能够以弱类型的方式获取任何内容,那么第二个选项可能更好。