为什么 memo.Lines 使用 TStrings 而不是 TStringList?

21
为什么Memo.Lines使用抽象类 TStrings?为什么不能使用TStringList
我需要在处理之前将其转换为TStringList吗?

2
TMemo.Lines is TStringList = False。实际上,这背后的对象是Windows API的包装器。存储由实现TMemo的Windows EDIT控件组织。"我在使用它之前应该将其转换为TStringList吗?" 不需要。你为什么要这样做呢? - David Heffernan
5
TStrings是一个较小的“契约”,为开发人员提供更大的灵活性。您可以与实现TStrings抽象类的任何类进行交互。 - Simon
1个回答

26

TMemo.LinesTListBox.ItemsTComboBox.Items等都声明为TStrings。注意,这是关于属性的说法!内部创建的类型分别为TMemoStringsTListBoxStringsTComboBoxStrings,它们都是TStrings的子类,并且在存储方式上有所不同。

为什么呢?为了实现互换性和互操作性。因此,每个TStrings的子类都具有相同的属性,因此可以进行以下操作:

Memo1.Lines := ListBox1.Items;

如何使用?嗯,像TMemo.Lines这样的TStrings属性就可以很好地起作用。您可以添加、删除、更改、更新和清除属性上的字符串(和对象),因为内部它是一个实现了所有这些交互的TMemoStrings。声明和实现分开。

但是当您需要任何特殊处理时,例如像TStringList提供的排序,那么您就需要帮助。您不能将TMemo.Lines强制转换或转换为TStringList,因为它不是一个TStringList,而是需要创建一个中间对象来进行特殊处理:

var
  Temp: TStringList;
begin
  Temp := TStringList.Create;
  try
    Temp.Assign(Memo1.Lines);
    Temp.Sort;
    Memo1.Lines.Assign(Temp);
  finally
    Temp.Free;
  end;
end;

1
好的,谢谢,这很有道理。所以我猜例如 Memo.Lines.Delete(0) 能够工作是因为它内部没有使用 TStrings? - Illiou
是的。当您在表单上放置一个备忘录组件时,如果没有出现“抽象编译器错误”,那么我们可以假设没有实例化抽象对象。 ;) - NGLN
1
肯定有更简洁的方法来原地排序。 - David Heffernan
5
调用Memo.Lines.Delete()会委托给适当的Win32 API调用来实际从UI控件中删除一行。不同的控件使用不同的API,因此它们使用不同的TStrings派生类。这就是使用像TStrings这样的抽象层的优势所在。调用者无需关心其内部实现方式。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接