问题描述
我想为泛型类定义一个类类型(类型别名)。我想这样做,所以单位b的用户可以访问TMyType而不使用单位a。
我有这样的单位:
I would like to define a class type (type alias) for a generic class. I would like to do this so users of unit b can have access to TMyType without using unit a.I have units like this:
unit a;
interface
type
TMyNormalObject = class
FData: Integer;
end;
TMyType<T> = class
FData: <T>;
end;
implementation
end.
unit b;
interface
type
TMyNormalObject = a.TMyNormalObject; // works
TMyType<T> = a.TMyType<T>; // E2508 type parameters not allowed on this type
implementation
end.
我已经找到了一个我不喜欢的可能的解决方法,因为它可以很容易地发现错误:
I already found a possible workaround which I don't like because it can introduce hard to find bugs:
TMyType<T> = class(a.TMyType<T>);
这种方法的问题是它引入了一个新的类类型,而a.TMyType实例不是一个b.TMyType(而a.TMyNormallClass是一个b.TMyNormalClass,反之亦然 - 它们指的是同一个类)。
The problem with this approach is that it introduces a new class type and an a.TMyType instance is not a b.TMyType (while a.TMyNormallClass is a b.TMyNormalClass and vice versa - they are referring to the same class).
推荐答案
p>
示例:
TMyClass<T> = class
end;
TMyClassClass<T> = class of TMyClass<T>; //E2508 type parameters not allowed on this type
呈现的解决方法如下所示: p>
The workaround that is presented looks like this :
TMyIntClass = TMyType<Integer>;
TMyIntClassClass = Class of TMyIntClass;
但是如同评论的那样,这将会击败泛型的整个想法,因为该类必须被子类化对于每个通用实例化,
But as commented, that would defeat the whole idea of generics, since the class would have to be subclassed for every generic instantiation.
这里也是一个类似的解决方法的链接,用于生成泛型类型的专门子类:。在这种情况下,它将如下所示:
Here is also a link to a similar workaround on generating a specialized subclass of a generic type: derive-from-specialized-generic-types. In this case it would look like this :
TMySpecialClass = Class(TMyType<Integer>);
更新:
RM提出的解决方法:
The workaround proposed by RM:
TMyType<T> = class(a.TMyType<T>);
可以使用以下方案实现类型安全:
can be implemented with type safety using following scheme:
unit Unita;
interface
type
TMyType<T> = class
Constructor Create;
end;
implementation
uses
Unitb;
constructor TMyType<T>.Create;
begin
Inherited Create;
//WriteLn( Self.QualifiedClassName,' ',Unitb.TMyType<T>.QualifiedClassName);
Assert(Self.QualifiedClassName = Unitb.TMyType<T>.QualifiedClassName);
end;
end.
unit Unitb;
interface
uses Unita;
type
TMyType<T> = class(Unita.TMyType<T>);
implementation
end.
Project Test;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
Unita in 'Unita.pas',
Unitb in 'Unitb.pas';
var
t1 : Unita.TMyType<Integer>;
t2 : Unitb.TMyType<Integer>;
t3 : TMyType<Integer>;
begin
try
//t1 := Unita.TMyType<Integer>.Create; //Exception EAssertionFailed !!
t2 := Unitb.TMyType<Integer>.Create;
t3 := TMyType<Integer>.Create;
ReadLn;
finally
//t1.Free;
t2.Free;
t3.Free;
end;
end.
创建通用类时,会进行一次测试,以检查创建的类是否从类型派生在单位b中宣布。因此,检测到从单位a创建此类的所有尝试。
When creating the generic class, a test is made to check that the created class is derived from the type declared in unit b. Thereby all attempts to create this class from unit a is detected.
更新2:
为了清楚起见,引用通用类类型为< T>
是不可能的,但泛型类的副本是正常的。
Just to be clear, a reference to a generic class, "class of type<T>
" is not possible, but a copy of a generic class is fine.
这篇关于是否可以在Delphi中为通用类创建一个类别别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!