Typecast通用类型转换为其他类型 [英] Typecast Generic type to other type
问题描述
我有一个基类
TEventMulticaster = class(Tobject)
public
过程Notify aMap:WideString);
end;
procedure TEventMulticaster.Notify(aMap:WideString);
begin
//做某事
end;
和派生的泛型类
TEventMulticaster< T> = class(TEventMulticaster)
public
procedure Notify(aMap:T);重新引入;
end;
procedure TEventMulticaster< T> .Notify(aMap:T);
begin
继承Notify(aMap)//错误
end;
当基类Notify调用它给我错误不兼容的类型:'WideString'和'T'
,当我做 ** Notify(WideString(aMap))**
它表示无效的类型转换
我的问题是如何将泛型类型转换为 WideString ,以便我可以调用基类 notify
procedure TEventMulticaster< T> .Notify(aMap:T);
begin
继承Notify(aMap);
end;
这里有一个通用的 aMap
参数,类型为 T
。类型 T
对它没有限制。它可以是任何类型。您正在寻求将 aMap
转换为 WideString
。编译器根本无法做到这一点。没有可以接受任意类型参数的转换转换,并将其转换为 WideString
。
您可以将 aMap
放入 TValue
中,然后调用 ToString
方法 TValue
。编译器至少会对此满意:
继承Notify(TValue.From< T>(aMap).ToString);
这可能会达到您的预期。或者可能不是。这一切都取决于 T
碰巧是什么。如果 T
是基本类型,如整数
或 string
,那么 TValue.ToString
几乎可以确保你所期望的。如果 T
更加深奥,那么谁知道这段代码是否会按照您的预期行事。你当然没有告诉我们如何将任意类型转换为文本。
我怀疑你对泛型没有把握,因为编译器必须知道如何在不知道泛型是什么的情况下编译该方法。在评论中您声明:
aMap不是类的类型
虽然你可能知道,编译器不会。从编译器的角度来看, T
可以是任何东西。泛型与实例化后发生编译的Smalltalk / C ++模板非常不同。
泛型功能允许您将约束应用于泛型。但是,这些都非常有限。你不能应用一个约束,它说,类型T将有一个明确的隐式转换为 WideString
。
正如我以前告诉过你的那样,我感到你正在为你对泛型的理解而挣扎。我认为,提出潜在的问题而不是您提出的解决方案会更有效率。
最后一点。 WideString
类型是COM BSTR
字符串类型的包装。在现代的Unicode感知Delphi中,只需在使用COM编写interop代码时使用 WideString
即可。你应该使用 string
而不是 WideString
。 字符串
类型是 UnicodeString
的别名,它是原生的Delphi Unicode字符串类型。
i have a base class
TEventMulticaster = class(Tobject)
public
procedure Notify(aMap: WideString);
end;
procedure TEventMulticaster.Notify(aMap: WideString);
begin
// Do something
end;
And a derived generic class
TEventMulticaster<T> = class(TEventMulticaster)
public
procedure Notify(aMap: T ); reintroduce;
end;
procedure TEventMulticaster<T>.Notify(aMap: T);
begin
inherited Notify(aMap) // ERROR
end;
when base class Notify is call it give me error "Incompatible types: 'WideString' and 'T'"
and when i do **Notify(WideString(aMap))**
it says invalid typecast
my question is how can i type cast generic type to "WideString" so that i can call base class notify
procedure TEventMulticaster<T>.Notify(aMap: T);
begin
inherited Notify(aMap);
end;
Here you have aMap
which is a generic argument, of type T
. The type T
has no constraints on it. It can be any type. You are seeking to convert aMap
to WideString
. The compiler simply has no way to do that. There is no over-arching conversion that can take an argument of arbitrary type and convert it to WideString
.
You could push aMap
into a TValue
, and then call the ToString
method of TValue
. The compiler will at least be satisfied with this:
inherited Notify(TValue.From<T>(aMap).ToString);
This might do what you expect. Or perhaps not. It all depends upon what T
happens to be. If T
is a fundamental type like Integer
or string
then TValue.ToString
will almost certainly do what you expect. If T
is more esoteric then who knows whether this code will behave as you expect. You certainly have not given us any indication as to how the arbitrary type is to be converted to text.
The thing that I suspect you are not grasping about generics is that the compiler has to know how to compile the method without knowing what the generic type is. In comments you state that:
aMap is not of type class
Whilst you might know that, the compiler does not. From the perspective of the compiler, T
can be anything at all. Generics are very different from Smalltalk/C++ templates where the compilation happens after instantiation.
The generics functionality does allow you to apply constraints to your generic type. However, these are quite limited. You cannot apply a constraint that says, type T will have a well-defined implicit conversion to WideString
.
As I have said to you before, I sense that you are struggling with your understanding of generics. I feel that it would be more productive for you to present the underlying problem rather than you proposed solution.
One final point. The WideString
type is a wrapper around the COM BSTR
string type. In modern Unicode aware Delphi you use WideString
just when writing interop code with COM. You should be using string
rather than WideString
. The string
type is an alias for UnicodeString
, the native Delphi Unicode string type.
这篇关于Typecast通用类型转换为其他类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!