首先,抱怨的不是编译器,而是 IDE。
编译器 并不关心您是否有同名的表单或其他类型,只要它们在不同的单元中即可。 VCL 中的一个著名示例是存在两种 TBitmap 类型,一种在 Graphics 中,另一种在 Windows 中。如果您需要明确说明您所指的类型,您只需在代码中限定类型名称,编译器就会按照它的指示进行操作。
bmpA: Graphics.TBitmap; // bmpA is a TBitmap as defined in the Graphics unit
bmpB: Windows.TBitmap; // bmpB is a TBitmap as defined in the Windows unit
没问题。
然而,Delphi 中的持久性框架确实关心您是否有同名的持久性类,因为持久性框架仅通过以下方式识别类型他们的不合格名。
这就是为什么 Delphi 的每个第三方组件框架都在其类名上使用前缀的原因。这不仅仅是虚荣或时尚。它确保一个库中的组件不会(通过 Delphi 持久性机制)与不同库中的另一个组件在同一个项目中使用时混淆。
底线:坚持为您的表单使用唯一名称,并在需要时找到其他方式来区分或切换它们。
如果没有有关您项目的更多详细信息,很难确切地建议如何管理您对正在使用的特定表单的引用。您可以从一个公共基类派生出两者,也可以为每个基类定义一个接口来实现。
例如(这只是一个说明性草图,不是推荐或完全可行的解决方案):
// Define the interface that your Receiver implementations
// must satisfy. This might include returning a reference to the implementing form.
//
// e.g. in a unit "uiReceiver"
type
IReceiver = interface
function Form: TForm; // returns the form using the common base type, not the specific implementation class
end;
// in unit uSDR
TfrmSDRReceiver = class(TForm, IReceiver)
..implements IReceiver as well as your SDR specific needs
end;
// in unit u7000
TfrmR7000SerialReceiver = class(TForm, IReceiver)
..implements IReceiver as well as your R7000 Serial specific needs
end;
// In uReceiver (some unit to "resolve" the receiver)
interface
uses
uSDR,
uR7000;
type
TReceiver = class
class function GetReceiver: IReceiver;
end;
implementation
class function TReceiver.GetReceiver: IReceiver;
begin
{$ifdef SDR}
result := frmSDRReceiver;
{$endif}
{$ifdef R7000}
result := frmR7000SerialReceiver;
{$endif}
end;
end.
然后,您的应用程序代码使用 uReceiver 单元(如果您想引用接口类型,例如在变量声明中,则使用 uiReceiver)并访问特定的 Receiver 通过提供的静态类实现,例如:
uses
uReceiver;
implementation
uses
uiReceiver;
..
var
rcvr: IReceiver;
begin
rcvr := TReceiver.GetReceiver;
rcvr.... // work with your receiver through the methods/properties on the interface
// You can also work with the receiver form, accessing all aspects
// common to any TForm via the Form function on the interface (assuming
// you chose to provide one):
rcvr.Form.Show;
..
end;