是否可以将泛型类的后代移至实现部分?

2023-12-30

我想从接口部分清除具体类,但编译器不允许这样做。 是否有机会使外部代码无法寻址具体类?

unit Unit2;

interface

uses
  System.SysUtils
  , System.Generics.Collections
  , System.Win.Registry
  ;
type
  IMyRegistry<T> = interface
    procedure WriteValue(const Key, Ident: string; const AValue: T);
    function ReadValue(const Key, Ident: string; const ADefVal: T): T;
  end;

  TMyRegistry<T> = class abstract(TInterfacedObject, IMyRegistry<T>)
  strict private
    class var FDefaultReg: IMyRegistry<T>;
    class var FRegistry: TRegistry;
    class var FDefKey: string;
  private
    class function GetDefKey: string;
    class function GetInstance: IMyRegistry<T>; static;
  protected
    procedure WriteValue(const Key, Ident: string; const AValue: T); virtual; abstract;
    function ReadValue(const Key, Ident: string; const ADefVal: T): T; virtual; abstract;
    function GoToKey(const AKeyName: string; const ACreateKey: Boolean = False): Boolean;
    class property InnerRegistry: TRegistry read FRegistry;
  public
    class constructor Create;
    class destructor Destroy;
    class property Default: IMyRegistry<T> read GetInstance;
  end;

  TDefaultMyRegistry<T> = class(TMyRegistry<T>)
  protected
    procedure WriteValue(const Key, Ident: string; const AValue: T); override;
    function ReadValue(const Key, Ident: string; const ADefVal: T): T; override;
  end;

  TMyRegistryFactory = class
  public
    class function GetMyRegistryConcrete<T>: IMyRegistry<T>;
  end;

  //TMyRegInteger = class(TMyRegistry<Integer>)
  //protected
    //procedure WriteValue(const Key, Ident: string; const AValue: Integer); override;
    //function ReadValue(const Key, Ident: string; const ADefVal: Integer): Integer; override;
  //end;

  EMyRegGenericException = class(Exception);
    EMyRegTypeNotSupported = class(EMyRegGenericException);

const
  cCompanyName = 'MyCompany';
  cProgramName = 'MyProgram';

resourcestring
  SRegTypeNotSupported = 'Operations are not supported for values of type "%s"';

implementation

uses
  Winapi.Windows
  , System.TypInfo;

type
  TMyRegInteger = class(TMyRegistry<Integer>)
  protected
    procedure WriteValue(const Key, Ident: string; const AValue: Integer); override;
    function ReadValue(const Key, Ident: string; const ADefVal: Integer): Integer; override;
  end;    


{ TMyRegistry<T> }

class constructor TMyRegistry<T>.Create;
begin
  inherited;
  FDefaultReg := TDefaultMyRegistry<T>.Create;
  FRegistry := TRegistry.Create;
  FRegistry.RootKey := HKEY_CURRENT_USER;
  FDefKey := GetDefKey;
end;

class destructor TMyRegistry<T>.Destroy;
begin
  FreeAndNil(FRegistry);
  inherited;
end;

class function TMyRegistry<T>.GetDefKey: string;
const
  cDefKey = '\Software\%s\%s\';
begin
  Result := Format(cDefKey, [cCompanyName, cProgramName]);
end;

class function TMyRegistry<T>.GetInstance: IMyRegistry<T>;
begin
  Result := FDefaultReg;
end;

function TMyRegistry<T>.GoToKey(const AKeyName: string;  const ACreateKey: Boolean): Boolean;
var
  sDestKeyName: string;
begin
  sDestKeyName := FDefKey + AKeyName;
  Result := FRegistry.OpenKey(sDestKeyName, False);
  if not Result and ACreateKey then
    Result := FRegistry.OpenKey(sDestKeyName, ACreateKey);
end;


{ TDefaultMyRegistry<T> }

function TDefaultMyRegistry<T>.ReadValue(const Key, Ident: string;  const ADefVal: T): T;
var
  tmpReg: IMyRegistry<T>;
begin
  Assert(TypeInfo(T) <> nil, 'Тип не определен');
  Result := ADefVal;
  if GoToKey(Key) then
    if InnerRegistry.ValueExists(Ident) then
    begin
      tmpReg := TMyRegistryFactory.GetMyRegistryConcrete<T>;
      if Assigned(tmpReg) then
        Result := tmpReg.ReadValue(Key, Ident, ADefVal);
    end;
end;

procedure TDefaultMyRegistry<T>.WriteValue(const Key, Ident: string; const AValue: T);
var
  tmpReg: IMyRegistry<T>;
begin
  inherited;
  if GoToKey(Key, True) then
  begin
    tmpReg := TMyRegistryFactory.GetMyRegistryConcrete<T>;
    if Assigned(tmpReg) then
      tmpReg.WriteValue(Key, Ident, AValue);
  end;
end;


{ TMyRegistryFactory }

class function TMyRegistryFactory.GetMyRegistryConcrete<T>: IMyRegistry<T>;
begin
  Result := nil;
  if TypeInfo(T) = TypeInfo(Integer) then
    Result := IMyRegistry<T>(IMyRegistry<Integer>(TMyRegInteger.Create)) //<<<  [DCC Error] Unit2.pas(155): E2506 Method ...
  else
    raise EMyRegTypeNotSupported.CreateFmt(
      SRegTypeNotSupported, [PTypeInfo(TypeInfo(T))^.Name]);
end;


{ TMyRegInteger }

function TMyRegInteger.ReadValue(const Key, Ident: string;
  const ADefVal: Integer): Integer;
begin
  Result := InnerRegistry.ReadInteger(Ident);
end;

procedure TMyRegInteger.WriteValue(const Key, Ident: string; const AValue: Integer);
begin
  inherited;
  InnerRegistry.WriteInteger(Ident, AValue);
end;

end.

如果将类声明“TMyRegInteger”移动到实现部分,则编译器会报告错误: “[DCC 错误] Unit2.pas(155): E2506 在接口部分中声明的参数化类型的方法不得使用本地符号 '.TMyRegInteger'”

in

class function TMyRegistryFactory.GetMyRegistryConcrete<T>: IMyRegistry<T>;
begin
  Result := nil;
  if TypeInfo(T) = TypeInfo(Integer) then
    Result := IMyRegistry<T>(IMyRegistry<Integer>(TMyRegInteger.Create)) //<<<<<

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以将泛型类的后代移至实现部分? 的相关文章

随机推荐

  • 使用 JFileChooser 设置默认保存扩展名

    我正在尝试使用保存文件JFileChooser 但是 我似乎遇到了一些麻烦 这是我的代码 if e getSource saveMenu JFileChooser chooser new JFileChooser chooser setFi
  • 如何创建比屏幕更大的视图?

    是否可以创建比屏幕更大的视图 我需要一个比设备屏幕宽度更大的视图 我在旋转动画中使用此视图 在旋转过程中 在动画视图之前不在屏幕上的部分将变得可见 有没有办法用android框架实现这种效果 Update 我尝试将父布局设置为比屏幕大得多
  • OpenCV VideoCapture 无法打开许多视频文件

    我在使用 OpenCV 类 VideoCapture 循环打开许多视频文件 例如 200 个 时遇到问题 您可以在下面找到我的代码 更具体地说 我的程序成功打开一定数量的视频 通常是 171 173 但无法打开其他视频 我什至尝试始终打开相
  • Python 3.x - 使用文本字符串作为变量名

    我试图通过使用来避免在代码中增加函数 def Return Label self number 带参数 任何想法如何使用字符串来定义可用于的变量名称 set价值StringVar 示例代码如下 import tkinter as tk fr
  • 在自定义对象上添加事件监听器

    我创建了一个具有多种方法的对象 其中一些方法是异步的 因此我想使用事件以便能够在方法完成时执行操作 为此 我尝试将 addEventListener 添加到该对象 jsfiddle http jsfiddle net 9d7nN var i
  • 如何在 onSaveInstanceState() 中存储值并检索?

    我试图将数组列表的值存储在onSavedInstanceState 并在 onCreate 方法中获取数组列表中的值 但它会引发类似无法暂停活动的错误 这是我的代码 public void onSaveInstanceState Bundl
  • NServiceBus Bus.Send().Register(callback) 不适用于 IIS/Windows Server 2008

    我已经为这个问题苦苦挣扎了几天 但我似乎无法弄清楚 我有一个托管在 IIS 和 Windows Server 2008 R2 上的简单 WCF Web 服务 Web Service的实现如下 var completionResult new
  • 如何使用新的Spring Security AuthorizationManager?

    Spring Security 已将 AccessDecisionManager 和 AccessDecisionVoter 这两个类替换为 AuthorizationManager 很不错 不幸的是 Spring Security 团队再
  • 如何按顺序将计数器写入文件?

    我需要按照出现次数最多到最少出现的顺序向文件写入一个计数器 但我遇到了一些麻烦 当我打印计数器时 它会按顺序打印 但是当我打电话时counter items 然后将其写入一个文件 它会乱序写入它们 我正在尝试使其成为这样 word 5 wo
  • 从 HIVE UDF 读取 HDFS 文件 - 执行错误,返回代码 101 FunctionTask。无法初始化类

    我们一直在尝试创建一个简单的 Hive UDF 来屏蔽 Hive 表中的某些字段 我们使用外部文件 放置在 HDFS 上 来抓取一段文本 以便对屏蔽过程进行加盐 看起来我们一切正常 但是当我们尝试创建外部函数时 它会抛出错误 org apa
  • 使用带有 ADFS 的系统登录 iOS 应用程序

    我有兴趣制作一个登录到使用 ADFS 和 SAML 单点登录的系统的应用程序 现在我很高兴阅读它 我只是想知道是否有任何特定于 iOS 平台的东西以及它如何集成 甚至可能与演示应用程序集成 我找到了这个网站 使用 SAML 和 OAuth
  • MonoMac 是否已被弃用?

    MonoMac 的页面似乎已被放弃 它的最后一次更新似乎是在几年前 因为它说 Mountain Lion 是 新 操作系统 AppKit 的新 Lion 和 Mountain Lion API MonoMac在Xamarin Studio中
  • 将 Angular 1 服务注入 Angular 4

    使用概述的过程here https angular io docs ts latest guide upgrade html making angularjs dependencies injectable to angular 我正在尝试
  • 奇怪的结果 javascript 比较

    我有一个关于 javascript 的入门级问题 当执行以下命令时 结果是 false true有些数字是相等的数 数 号码号码号码 为什么前两个值不同 为什么第一个是错误的 JS function sort3 a b c document
  • 如何向老板解释代码/资源优化的重要性?

    啊啊啊每次都好郁闷 我们的托管公司有一个专用服务器 每次我必须写下一个新应用程序 或添加到预先存在的应用程序 时 我都会 损失 一些时间来优化许多行为的代码 减少数据库查询 优化数据库结构 减少带宽等 取决于应用程序应该执行的操作 显然 重
  • 进行更改后将 Power BI 嵌入报表保存在数据库中

    我正在使用 power bi 嵌入式包来嵌入 power bi 报告 https github com microsoft powerbi client react https github com microsoft powerbi cl
  • 在 Swing 中未按下鼠标的组件上监听鼠标释放事件

    是否可以监听未按下鼠标的组件上的鼠标释放事件 我知道当鼠标被释放时MouseListener mouseReleased 当鼠标按下时 即使光标位于其他组件上方 也会在该组件的侦听器上调用 如何通知组件或其侦听器鼠标位于其上方并且已释放 如
  • 当 UITableView 高度改变时更新其他元素的约束

    我有一个UITableView其中我在自动布局中将高度定义为 200 基于此 我在其下面布置了其他元素 例如UITextField等等 之后在运行时我从服务器获取数据并填充UITableView因此我正在更新UITableView的高度基于
  • 如何将 std::enable_if 与自推导返回类型一起使用?

    C 14 http en wikipedia org wiki C 14 Function return type deduction将具有可以根据返回值推断其返回类型的函数 auto function return hello world
  • 是否可以将泛型类的后代移至实现部分?

    我想从接口部分清除具体类 但编译器不允许这样做 是否有机会使外部代码无法寻址具体类 unit Unit2 interface uses System SysUtils System Generics Collections System W