如何实现模型类与Protobuf消息的强制转换?解决CS1106错误
解决CS1106错误:实现自定义模型与Protobuf消息的强制转换
你的代码触发CS1106错误的核心原因是C#扩展方法的定义规则:扩展方法必须放在静态、非泛型的类中,且不能是抽象方法(抽象方法需要子类重写,但扩展方法是静态的,无法被继承重写)。你原来的抽象泛型类+抽象扩展方法的写法完全违反了这些规则,所以需要调整实现思路。
下面给出两种可行的解决方案,都能实现“强制自定义模型类实现与对应Protobuf消息的转换”的需求:
方案一:使用转换接口+静态扩展类
这种方案通过接口强制模型类实现转换逻辑,同时用扩展方法保持调用的简洁性。
1. 定义转换接口
首先定义一个泛型接口,约束模型必须实现转换到指定Protobuf消息的方法:
public interface IMessageConvertible<TMessage> where TMessage : Google.Protobuf.IMessage { TMessage ToMessage(); }
2. 模型类实现接口
让你的自定义模型类(继承ModelBase)实现上述接口,强制编写转换逻辑:
public class UserModel : ModelBase, IMessageConvertible<UserProto> { public string Username { get; set; } public int UserAge { get; set; } // 必须实现的转换方法 public UserProto ToMessage() { return new UserProto { Name = this.Username, Age = this.UserAge }; } }
3. 编写静态扩展类
创建静态非泛型类,封装扩展方法调用接口的转换逻辑,这样就能用模型实例.ToMessage()的方式调用:
public static class MessageConversionExtensions { public static TMessage ToMessage<TMessage>(this IMessageConvertible<TMessage> model) where TMessage : Google.Protobuf.IMessage { return model.ToMessage(); } }
调用示例
var userModel = new UserModel { Username = "Bob", UserAge = 28 }; UserProto protoMsg = userModel.ToMessage();
方案二:使用抽象基类约束转换
如果你的模型类都继承自ModelBase,可以直接修改基类为泛型抽象类,强制子类实现转换方法:
1. 修改抽象基类
public abstract class ModelBase<TMessage> where TMessage : Google.Protobuf.IMessage { // 强制子类实现转换方法 public abstract TMessage ToMessage(); }
2. 模型类继承并实现
public class OrderModel : ModelBase<OrderProto> { public string OrderId { get; set; } public decimal TotalAmount { get; set; } public override OrderProto ToMessage() { return new OrderProto { Id = this.OrderId, Amount = (double)this.TotalAmount }; } }
调用示例
直接调用基类定义的抽象方法即可,也可以额外写扩展方法(可选):
var orderModel = new OrderModel { OrderId = "ORD-001", TotalAmount = 99.9m }; OrderProto orderProto = orderModel.ToMessage();
两种方案对比
- 接口方案:灵活性更高,一个模型类可以实现多个转换接口(比如同时转换到不同的Protobuf消息类型),但需要每个模型显式声明实现接口。
- 抽象基类方案:约束性更强,所有继承
ModelBase<TMessage>的类必须实现转换,但每个模型只能对应一种Protobuf消息类型。
内容的提问来源于stack exchange,提问作者Marin Althuis
相关产品推荐
相关产品推荐

