3

假设我有一个用 c# 实现的类层次结构,带有Protobuf.net. (还有一个Rectangle实现 的类Shape,但为简洁起见,我省略了它。)

[ProtoContract]
[ProtoInclude(1, typeof(Circle))]
public class Shape {
}

[ProtoContract]
public class Circle : Shape {

    [ProtoMember(1)]
    public int Radius {get;set;}
}

我想在 TypeScript 中使用protobuf.js. 但是,我似乎无法弄清楚如何将“oneof”字段映射回子类。

这是我能想到的最好的:

// It's not possible to make this inherit from 'Shape'
class Circle extends Message<Circle> {
  @Field.d(1, "int32")
  radius: number;
}

class Shape extends Message<Shape> implements IShape {
  @Field.d(1, Circle)
  circle: Circle;

  @OneOf.d("circle") // ,"rectangle"
  which: string;

  // Implements the property on ICircle
  get radius(): number {
    return this.circle.radius;
  }
}

interface IShape {
}

interface ICircle extends IShape {
  radius: number;
}

function isCircle(shape: IShape): shape is ICircle {
  return (shape as any).which === "circle";
}

const shape = new Shape({
  circle: new Circle({ radius: 5 }),
  which: "circle"
});

const buffer = Shape.encode(shape).finish();
const decoded = Shape.decode(buffer);

if (isCircle(decoded)) {
  const itsACircle: ICircle = decoded;
  // Do something
}

这对我来说感觉很奇怪,因为:

  1. 我们必须将所有可能的子类字段公开为基Shape类的属性(在本例中为 的radius属性Circle)。
  2. 没有一个类实际实现ICircle,所以如果我们未能正确地公开某些属性,编译器不会警告我们。
  3. 类型保护依赖于强制转换any

任何人都可以提出更好的方法来实现这一目标吗?

4

0 回答 0