官方文檔稱它們是可選的。我知道COM interop需要每個接口的唯一標識符,但是我看到的每個接口示例都有一個GUID,不管它是否與COM一起使用?如果不包含GUID,是否有任何好處?是否需要在Delphi中使用GUID?
回答
我注意到一些方法,如Supports
(確定一個類遵循特定的接口)要求你定義一個GUID纔可以使用他們。
注::
This page以下信息證實了這一點的SysUtils單元中提供了一個 重載函數調用支持 返回真或假時類 類型和實例支持表示的 特定接口一個 GUID。支持功能用於 德爾福的方式是和 運營商。的顯著差異 是,支架函數可以採取 作爲右操作數任一個GUID或 與 GUID相關聯的接口的類型,而是並作爲取的名字的類型 。有關 is和as的更多信息,請參見Class References。
這裏的一些interesting information about interfaces,其中規定:
爲什麼一個接口必須 唯一識別的?答案是 簡單:因爲Delphi類可以實現 多個接口。當一個 應用程序正在運行時,必須有一個 是一個機制,它將從 實現中獲取指針 到適當的接口。 如果對象實現了 接口並獲得指向 的指針,則通過GUID可以找到 。 的實現是 。
強調添加在兩個引號中。
閱讀這篇文章也讓你意識到QueryInterface
(它需要一個GUID)在幕後出於諸如引用計數的原因而被使用。
只有當你需要你的接口是compatible with COM。
不幸的是,這還包括使用is
,as
運營商和QueryInterface
,Supports
職能 - 缺乏是相當有限的。所以,雖然沒有嚴格要求,但使用GUID可能更容易。否則,你只剩相當簡單的用法:
type
ITest = interface
procedure Test;
end;
ITest2 = interface(ITest)
procedure Test2;
end;
TTest = class(TInterfacedObject, ITest, ITest2)
public
procedure Test;
procedure Test2;
end;
procedure TTest.Test;
begin
Writeln('Test');
end;
procedure TTest.Test2;
begin
Writeln('Test2');
end;
procedure DoTest(const Test: ITest);
begin
Test.Test;
end;
procedure DoTest2(const Test: ITest2);
begin
Test.Test;
Test.Test2;
end;
procedure Main;
var
Test: ITest;
Test2: ITest2;
begin
Test := TTest.Create;
DoTest(Test);
Test := nil;
Test2 := TTest.Create;
DoTest(Test2);
DoTest2(Test2);
end;
這是不對的;請參閱@ eagle的答案。如果沒有GUID,可以使用非COM接口的唯一方法是不安全的硬性強制轉換。 – 2010-06-07 19:12:36
如果我在上面添加的示例中存在任何不安全的情況,請讓我知道,謝謝。 – 2010-06-07 19:35:24
@Craig:我不確定接口中是否存在「不安全的硬轉換」,因爲編譯器仍然需要某種方法來定位正在使用的接口的接口表。 – 2010-06-07 20:20:15
- 1. 是否需要在onActivityResult()中使用super.onActivityResult()?
- 2. 我是否需要在Delphi中完成記錄數組?
- 3. 是否需要使用imap_close?
- 4. 是否需要使用Clonable?
- 5. 下拉使用的IList需要的Guid
- 6. 當dcu存在時,Delphi在編譯時是否需要dfm?
- 7. 是否需要在此處使用#import?
- 8. 是否需要在這裏使用ThreadLocal?
- 9. C#COM可見類型:是否需要GUID?
- 10. Ajax是否總是需要使用node.js?
- 11. Razor是否需要MVC3,還是隻能在.NET中使用它?
- 12. 這裏是否需要使用eval?
- 13. 我是否需要使用MultipleIterator的foreach?
- 14. 是否需要使用BigDecimal.new方法?
- 15. Process.Kill後是否需要使用Process.WaitForExit?
- 16. SimpleDateFormat - 您是否需要使用RegEx?
- 17. 需要說明這是否使用typedef
- 18. 我是否需要使用ReaderWriterLockSlim的MemoryBarrier?
- 19. 如果使用System.Threading.Timer,是否需要BackgroundWorker?
- 20. 使用Sitecore MaxMind是否需要Sitecore DMS
- 21. 彈簧:是否需要使用@Resource
- 22. 使用camel時,cxf:rsServer是否需要jaxrs:server?
- 23. 使用ActionController :: Live是否需要睡眠?
- 24. 是否需要使用var foo = new RegExp?
- 25. 使用AddHandler時,是否需要EnterWriteLock?
- 26. 使用ARC是否NSMutableArray需要屬性?
- 27. 我是否需要使用MultipleActiveResultSets feautre?
- 28. bscmake是否需要使用Visual Studio 2010?
- 29. 我是否需要使用「document.getElementById」
- 30. Java是否需要使用Red5
另外,值得注意的是,試圖在接口中使用'is'或'as'類型轉換涉及其中的一個調用(我忘記了這些調用),因此您需要一個GUID來執行此操作。 – 2010-06-07 18:58:32
所以簡短的答案是,雖然GUID是可選的不使用它們限制了你可以用接口做什麼。 – 2010-06-07 20:00:14
需要使用'Supports'函數是我爲接口定義GUID的唯一原因。 – 2012-04-16 09:51:42