概观
不完全确定这个问题措辞是否合适,但我之前曾问过这个与这个问题有关的问题:How do I correctly implement a Set in a class as a property?
我喜欢尽可能地将代码保持为短,最小和可读,这是我认为某些代码可以写得更好但我遇到问题的地方.
首先,有两种方法可以读取Set中的值:
漫长的道路:
if (Delphi1 in IDECompatibility) then CheckListBox1.Checked[0] := True; if (Delphi2 in IDECompatibility) then CheckListBox1.Checked[1] := True; if (Delphi3 in IDECompatibility) then CheckListBox1.Checked[2] := True;
更清洁,更短,更好的方式:
CheckListBox1.Checked[0] := (Delphi1 in IDECompatibility); CheckListBox1.Checked[1] := (Delphi2 in IDECompatibility); CheckListBox1.Checked[2] := (Delphi3 in IDECompatibility);
现在我想用另一种方式来设置值.
目前,我所知道的唯一方法是漫长的道路:
if CheckListBox1.Checked[0] then IDECompatibility := IDECompatibility + [Delphi1] else IDECompatibility := IDECompatibility - [Delphi1]; if CheckListBox1.Checked[1] then IDECompatibility := IDECompatibility + [Delphi2] else IDECompatibility := IDECompatibility - [Delphi2]; if CheckListBox1.Checked[2] then IDECompatibility := IDECompatibility + [Delphi3] else IDECompatibility := IDECompatibility - [Delphi3];
如果可能的话,我想做这样的事情:
IDECompatibility[Delphi1] := CheckListBox1.Checked[0]; // Array type required IDECompatibility[Delphi2] := CheckListBox1.Checked[1]; // Array type required IDECompatibility[Delphi3] := CheckListBox1.Checked[2]; // Array type required
有排除和包含成员,但我不确定这里是否需要这些成员.
因此,如上所述 – 是否有更简单的方法来定义基于布尔值的枚举类型?
谢谢.
解决方法
不,目前在Delphi中没有可用于
set
类型的数组访问.我建议创建一个辅助索引属性,它可以模仿像访问一样的数组,并且会隐藏包含或排除集合中元素所需的代码.
从我到目前为止看到的情况来看,人们通常会对具有Is或Has前缀的基本访问权限的属性进行前缀.在您的情况下,我将遵循此规则并创建一个名为HasIDECompatibility的属性,或者说IsIDECompatible.此属性将为布尔类型,并且将具有一个getter,通过该getter可以返回元素是否在内部set字段内的信息.在setter中,它将根据输入值将元素包含或排除到集合中.
在更通用的代码中,它将是:
type TElement = ( Element1,Element2,Element3 ); TElements = set of TElement; TMyClass = class private FElements: TElements; function GetElement(Kind: TElement): Boolean; procedure SetElement(Kind: TElement; Value: Boolean); public // this property is for direct access to the set field; if your class would // be a TComponent descendant and you'd publish this property,you'd see it // in the Object Inspector represented by a set of check Boxes property Elements: TElements read FElements write FElements; // this property is just a helper for array like access to the internal set // field property HasElement[Kind: TElement]: Boolean read GetElement write SetElement; end; implementation { TMyClass } function TMyClass.GetElement(Kind: TElement): Boolean; begin Result := Kind in FElements; end; procedure TMyClass.SetElement(Kind: TElement; Value: Boolean); begin if Value then Include(FElements,Kind) else Exclude(FElements,Kind); end;
并举例说明:
procedure TForm1.Button1Click(Sender: TObject); var MyClass: TMyClass; begin MyClass := TMyClass.Create; try // write elementary property value MyClass.HasElement[Element1] := CheckBox1.Checked; MyClass.HasElement[Element2] := CheckBox2.Checked; // read elementary property value CheckBox3.Checked := MyClass.HasElement[Element1]; CheckBox4.Checked := MyClass.HasElement[Element2]; // or you can access MyClass.Elements set at once as you were used to do // which gives you two ways to include or exclude elements to the set finally MyClass.Free; end; end;