格式化类型声明,包含许多[Attributes]以提高可读性

时间:2013-01-31 07:46:44

标签: delphi coding-style attributes

最近我发现自己依赖于自定义[属性]分配。我正在寻求创建我经常使用的VCL控件的RTTI和Generics变体;我的目的是将样板代码量减少到最少,我发现RTTI,匿名方法和属性 awesome

我有一个不寻常的问题。由于我最终使用了很多[属性],因此我需要可读方式来格式化此代码。可能听起来像一个微不足道的问题,但我对我的格式和缩进非常着迷。属性的问题在于IDE没有以特殊方式格式化它们。在具有[Attribute]声明的多个字段声明的块中,您很难猜测什么是类型,什么是属性,什么属性适用于哪个字段。这是一个最小的例子:

type
  [OneAttribute('SomeParam', 7), AnOtherAttribute]
  TSomething = class
  public
    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    FieldName: string;
    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    OtherField: Integer;
    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    function Sum(a,b:Integer):Currency;
    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    property Name:string read FieldName write FieldName;
  end;

我在上面的示例中构建这些[Attributes]的方式是C#代码中最常见的方式;不幸的是我没有看到使用属性的Delphi代码的例子,除了我自己的。这对于C#稍有好处,因为您不太可能将属性应用于实际字段,更有可能将其应用于propertiesfunctions;因为在C#中函数实现紧跟在它的声明之后(对于属性来说是相同的),所以你得不到与Delphi相同的块;函数和属性声明自然是分开的,因此对代码的浏览不会受到属性使用的阻碍。

我尝试了与delphi相关的“样式”信息的明显来源。 Delphi 2010中的代码格式化程序根本不理解属性声明!在上面的示例中,如果我删除public关键字并运行内置代码格式化器,则第一行Attributes声明在class关键字后面移动一行,就像它声明一个祖先类一样

我围绕着Delphi 2010源代码。要么我的grep-fu严重失败,要么在整个Delphi 2010源代码中绝对没有使用属性。为了清楚起见,在尝试grep实际使用属性之后(很难因为使用了方括号并且它们很少意味着它是属性声明)我开始为TCustomAttribute进行grepping:没有{{1}的后代在任何地方,显然没有使用属性。

最后的问题是:

如何格式化[属性]以提高可读性?

我的最新解决方案如下:

TCustomAttribute

我通常使用两列缩进;对于属性,我正在考虑将属性声明从左向左移动;总是有空间,因为我的类型,字段,方法和属性总是至少有2列右缩进(对于类型)或4对于类成员。像这样的左缩进似乎与现有的不使用属性的声明很好地融合,我希望属性“脱颖而出”,所以左缩进比右缩进更好。

你怎么看?你有更好的想法吗?

1 个答案:

答案 0 :(得分:7)

根据要求给出答案。

我使用的是第一个版本,只需在每个版本之后添加空白行。并且可选地,在“功能分离”的一组属性/方法属性对之后有两个空行。我也知道重复可见性说明符来分离方法/属性的功能组。

它需要更多的屏幕空间,但它有帮助..

type
  [OneAttribute('SomeParam', 7), AnOtherAttribute]
  TSomething = class
  public
    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    FieldName: string;

    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    OtherField: Integer;

    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    function Sum(a,b:Integer):Currency;

    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    property Name:string read FieldName write FieldName;

  public
    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    TableName: string;

    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    OtherTable: Integer;

    [OneAttribute('SomeParam', 7), AnOtherAttribute]
    function TableSum(a,b:Integer):Currency;
  end;