C# 与多个定义C的接口#

C# 与多个定义C的接口#,c#,inheritance,interface,enums,C#,Inheritance,Interface,Enums,我有两个基本的消息枚举,我把它们放进一个接口来控制它们。然而,当我这样做时,我需要支持遗留消息,同时仍然在中添加新消息。最好的方法是什么 这是Msg界面的总体思路: public interface Msg { /// <summary> /// Gets the ID of the message /// </summary> Legacy_Msgs MessageId { get; } //New_Msgs MessageId

我有两个基本的消息枚举,我把它们放进一个接口来控制它们。然而,当我这样做时,我需要支持遗留消息,同时仍然在中添加新消息。最好的方法是什么

这是
Msg
界面的总体思路:

public interface Msg
{
    /// <summary>
    /// Gets the ID of the message
    /// </summary>
    Legacy_Msgs MessageId { get; }
    //New_Msgs MessageId { get; }    // How implement use this?

    /// <summary>
    /// Converts the message to a byte array representation
    /// </summary>
    byte[] MsgBytes { get; }
}
公共接口消息
{
/// 
///获取消息的ID
/// 
遗留_Msgs MessageId{get;}
//New_Msgs MessageId{get;}//如何使用它?
/// 
///将消息转换为字节数组表示形式
/// 
字节[]MsgBytes{get;}
}
然而,我的问题是,为
new_Msgs
提供一个新的接口,继承
Msg
并覆盖
MessageId
,或者从效率的角度来看,为
new_Msg
枚举提供一个全新的
NewMsg
接口是否更有意义。

我意识到这两种解决方案都可以工作,但我想知道,作为另一个开发人员,考虑这种解决方案,还有什么更有意义呢?

接口不能覆盖,但您可以通过接口向合同中添加新项目

如果行为在实现之间发生变化,导致它们不向后兼容,那么您应该创建一个与旧接口/实现没有关系的全新接口/实现,因为有人可以创建新接口/实现的实例,并将其传递给期望使用旧接口/实现的使用者


单个实现可以实现两个接口,以尽可能保持兼容性。如果接口的成员重叠,则可以使用显式接口实现来同时维护这两个接口

接口无法覆盖,但您可以通过接口将新项目添加到合同中

如果行为在实现之间发生变化,导致它们不向后兼容,那么您应该创建一个与旧接口/实现没有关系的全新接口/实现,因为有人可以创建新接口/实现的实例,并将其传递给期望使用旧接口/实现的使用者


单个实现可以实现两个接口,以尽可能保持兼容性。如果接口的成员重叠,则可以使用显式接口实现来同时维护这两个接口

这种结构可能会给您带来更大的灵活性,同时让您的
IMsg
合同与消费者保持一致

// the following three MsgId contracts don't have to be contracts at all (the actual types can be specified in generic IMsg directly), but if one ID type is wildly different in nature than the other, an interface such as this might make sense.

public interface IMsgId
{
 // ?
}

public interface INewMsgId : IMsgId
{
}

public interface ILegacyMsgId : IMsgId
{
}

public interface IMsg<out TId>
   where TId : IMsgId
{
   TId MessageId { get; }

   byte[] MsgBytes { get; }
}

// if it is sensible, you can use the following interfaces to create definitive new and legacy message contracts

public interface INewMsg : IMsg<INewMsgId>
{
}

public interface ILegacyMsg : IMsg<ILegacyMsgId>
{
}
//以下三个MsgId契约根本不必是契约(实际类型可以直接在通用IMsg中指定),但是如果一个ID类型与另一个ID类型在性质上有很大不同,那么这样的接口可能是有意义的。
公共接口IMsgId
{
// ?
}
公共接口INewMsgId:IMsgId
{
}
公共接口ILegacyMsgId:IMsgId
{
}
公共接口IMsg
其中TId:IMsgId
{
TId消息ID{get;}
字节[]MsgBytes{get;}
}
//如果合理的话,您可以使用以下接口来创建最终的新消息契约和旧消息契约
公共接口INewMsg:IMsg
{
}
公共接口ILegacyMsg:IMsg
{
}
下面是一个实施示例:

public class LegacyMsgId : ILegacyMsgId
{
    public LegacyMsgId(int id)
    {
      Id = id;
    }

    public int Id { get; private set; }


    public override string ToString()
    {
        return "Legacy Message #" + Id;
    }
}

public class NewMsgId : INewMsgId
{
    public NewMsgId(int id)
    {
        Id = id;
    }

    public int Id { get; private set; }

    public override string ToString()
    {
        return "New Message #" + Id;
    }
}

public class NewMsg : INewMsg
{
    public NewMsg(int id)
    {
        MessageId = new NewMsgId(id);
    }

    public NewMsgId MessageId { get; private set; }

    INewMsgId IMsg<INewMsgId>.MessageId { get { return MessageId; } }

    public byte[] MsgBytes { get; private set; }
}

public class LegacyMsg : ILegacyMsg
{
    public LegacyMsg(int id)
    {
        MessageId = new LegacyMsgId(id);
    }

    public LegacyMsgId MessageId { get; private set; }

    ILegacyMsgId IMsg<ILegacyMsgId>.MessageId { get { return MessageId; } }

    public byte[] MsgBytes { get; private set; }
}
公共类LegacyMsgId:ILegacyMsgId
{
公共LegacyMsgId(int-id)
{
Id=Id;
}
public int Id{get;private set;}
公共重写字符串ToString()
{
返回“遗留消息#”+Id;
}
}
公共类NewMsgId:INewMsgId
{
公共NewMsgId(int-id)
{
Id=Id;
}
public int Id{get;private set;}
公共重写字符串ToString()
{
返回“新消息”#“+Id;
}
}
公共类NewMsg:INewMsg
{
公共NewMsg(int-id)
{
MessageId=新的NewMsgId(id);
}
public NewMsgId MessageId{get;private set;}
INewMsgId IMsg.MessageId{get{return MessageId;}}
公共字节[]MsgBytes{get;private set;}
}
公共类LegacyMsg:ILegacyMsg
{
公共LegacyMsg(int-id)
{
MessageId=新的LegacyMsgId(id);
}
public LegacyMsgId MessageId{get;private set;}
ILegacyMsgId IMsg.MessageId{get{return MessageId;}}
公共字节[]MsgBytes{get;private set;}
}
使用方法:

var messages = new List<IMsg<IMsgId>>();
messages.Add(new NewMsg(20));
messages.Add(new LegacyMsg(11));

foreach(var message in messages)
{
    Console.WriteLine(message.MessageId);
}
var messages=newlist();
添加(新消息(20));
添加(新的LegacyMsg(11));
foreach(消息中的var消息)
{
Console.WriteLine(message.MessageId);
}

这种结构可能会给您带来更大的灵活性,同时让您的
IMsg
合同与消费者保持一致

// the following three MsgId contracts don't have to be contracts at all (the actual types can be specified in generic IMsg directly), but if one ID type is wildly different in nature than the other, an interface such as this might make sense.

public interface IMsgId
{
 // ?
}

public interface INewMsgId : IMsgId
{
}

public interface ILegacyMsgId : IMsgId
{
}

public interface IMsg<out TId>
   where TId : IMsgId
{
   TId MessageId { get; }

   byte[] MsgBytes { get; }
}

// if it is sensible, you can use the following interfaces to create definitive new and legacy message contracts

public interface INewMsg : IMsg<INewMsgId>
{
}

public interface ILegacyMsg : IMsg<ILegacyMsgId>
{
}
//以下三个MsgId契约根本不必是契约(实际类型可以直接在通用IMsg中指定),但是如果一个ID类型与另一个ID类型在性质上有很大不同,那么这样的接口可能是有意义的。
公共接口IMsgId
{
// ?
}
公共接口INewMsgId:IMsgId
{
}
公共接口ILegacyMsgId:IMsgId
{
}
公共接口IMsg
其中TId:IMsgId
{
TId消息ID{get;}
字节[]MsgBytes{get;}
}
//如果合理的话,您可以使用以下接口来创建最终的新消息契约和旧消息契约
公共接口INewMsg:IMsg
{
}
公共接口ILegacyMsg:IMsg
{
}
下面是一个实施示例:

public class LegacyMsgId : ILegacyMsgId
{
    public LegacyMsgId(int id)
    {
      Id = id;
    }

    public int Id { get; private set; }


    public override string ToString()
    {
        return "Legacy Message #" + Id;
    }
}

public class NewMsgId : INewMsgId
{
    public NewMsgId(int id)
    {
        Id = id;
    }

    public int Id { get; private set; }

    public override string ToString()
    {
        return "New Message #" + Id;
    }
}

public class NewMsg : INewMsg
{
    public NewMsg(int id)
    {
        MessageId = new NewMsgId(id);
    }

    public NewMsgId MessageId { get; private set; }

    INewMsgId IMsg<INewMsgId>.MessageId { get { return MessageId; } }

    public byte[] MsgBytes { get; private set; }
}

public class LegacyMsg : ILegacyMsg
{
    public LegacyMsg(int id)
    {
        MessageId = new LegacyMsgId(id);
    }

    public LegacyMsgId MessageId { get; private set; }

    ILegacyMsgId IMsg<ILegacyMsgId>.MessageId { get { return MessageId; } }

    public byte[] MsgBytes { get; private set; }
}
公共类LegacyMsgId:ILegacyMsgId
{
公共LegacyMsgId(int-id)
{
Id=Id;
}
public int Id{get;private set;}
公共重写字符串ToString()
{
返回“遗留消息#”+Id;
}
}
公共类NewMsgId:INewMsgId
{
公共NewMsgId(int-id)
{
Id=Id;
}
public int Id{get;private set;}
公共重写字符串ToString()
{
返回“新消息”#“+Id;
}
}
公共类NewMsg:INewMsg
{
公共NewMsg(int-id)
{
MessageId=新的NewMsgId(id);
}
public NewMsgId MessageId{get;private set;}
INewMsgId IMsg.MessageId{get{retu
// let Msg be a dumb data object
public interface IMsg
{
    int Id { get; }
    byte[] Data { get; }
}

// and then keep their types weakly-typed
private readonly Dictionary<int, String> MessageNames;

// and you can also provide various type-based functionality
// during runtime
private readonly Dictionary<int, IParser> Parsers;