Typecast通用类型转换为其他类型 [英] Typecast Generic type to other type

查看:194
本文介绍了Typecast通用类型转换为其他类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基类

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆