-
Notifications
You must be signed in to change notification settings - Fork 21
使用 Thrifty 定义 thrift 结构
Anders Xiao edited this page Dec 1, 2017
·
1 revision
Thrifty 通过 ThriftStructAttribute、ThriftFieldAttribute 特性来描述一个结构。
任何的 thrift 标准 IDL 中的 struct 都可以通过特性使用 C# 代码来定义:
使用常规定义
考虑如下 IDL:
enum EnOpType {
CMD_OK = 0,
CMD_EXIT = 2001,
CMD_ADD = 2002
}
struct user {
1: required i32 userId;
2: required string userName;
3: optional EnOpType cmd_code;
4: optional string language = “english”;
5: list<i64> ID;
}
使用 Thrifty 来定义可表示为
public enum EnOpType
{
CMD_OK = 0,
CMD_EXIT = 2001,
CMD_ADD = 2002
}
[ThriftStruct("user")]
public class User
{
[ThriftField(1, Name = "userId")]
public int UserId { get; set;}
[ThriftField(2, Name = "userName")]
public string UserName { get; set;}
[ThriftField(3, Name = "cmd_code"]
public EnOpType? CmdCode { get; set;}
[ThriftField(4, Name = "language")]
public string Language { get; set;} = "english";
[ThriftField(5)] //ThriftFieldAttribute 的 Name 并不是必须赋值的,默认使用属性名
public IList<long> ID { get; set;}
}
注意
ThriftStructAttribute 默认使用类型作为 Name, 也可以显示指定,同样,的 ThriftFieldAttribute 并不是必须赋值的,默认使用属性名
使用构造函数
如上例所属的 User 类型,现在考虑如果 UserId 和 UserName 为只读,只允许通过构造函数传入,可以通过如下定义实现:
[ThriftStruct("user")]
public class User
{
public User([ThriftField(1)]string userId, [ThriftField(2)]user name)
{
this.UserId = userId,
this.UserName = name
}
[ThriftField(1, Name = "userId")]
public int UserId { get;}
[ThriftField(2, Name = "userName")]
public string UserName { get;}
[ThriftField(3, Name = "cmd_code"]
public EnOpType? CmdCode { get; set;}
[ThriftField(4, Name = "language")]
public string Language { get; set;} = "english";
[ThriftField(5)] //ThriftFieldAttribute 的 Name 并不是必须赋值的,默认使用属性名
public IList<long> ID { get; set;}
}
说明,构造函数中 ThriftFieldAttribute 用来告知 Thrifty 反序列化对象时使用哪个字段来传递参数,参数上的 ThriftFieldAttribute 并不要求 Name 对应,只要求数字(field id)和属性对应即可。
C# 类继承
ThriftFieldAttribute 描述的字段可以被子类继承,但 ThriftStructAttribute 并不会对继承类有效 。 使用继承类时,要求子类的 ThriftFieldAttribute 特性上的 id 必须在整个继承链上唯一
考虑如下 C# 类型,继承自上例中的 User 类:
[ThriftStruct("AgeUser")]
public class User2 : User
{
public User([ThriftField(1)]string userId, [ThriftField(2)]user name)
: base(userId, name)
{
this.UserId = userId,
this.UserName = name
}
[ThriftField(6, Name = "age")]
public int Age{ get; set;}
}
User2 对应 IDL 如下:
struct AgeUser {
1: required i32 userId;
2: required string userName;
3: optional EnOpType cmd_code;
4: optional string language = “english”;
5: list<i64> ID;
6: required i32 age;
}