一千萬個為什麽

搜索

Delphi Generics>具有默認值的字典

我想有一個字典,當找不到搜索鍵時返回默認值。閱讀文檔:

Generics.Collections.Tdictionary [...]此類提供映射[...]和初始內容。

1 - 怎麽樣?有沒有辦法做到這一點ala Python:{1:'one'; 2:'兩個'}?

Generics.Collections.TDictionary.TryGetValue [...]如果給定的鍵在字典中並且在Value中提供其值,則TryGetValue返回true。否則,它返回false,並將Value設置為Tvalue的默認值類型。

2 - 如何設置此默認值?我找不到一個構造函數(可能我剛剛在錯誤的地方搜索過。我期待像“構造函數Create(DefaultValue:TValue);”)

所以我正在嘗試實現自己的(可能沒有必要。見上文):

代碼是(歡迎評論和建議!):

unit Util;

interface

uses
    Generics.collections;

type

    //
   //Dictionary with default response
    //
    TDefaultDictonary = class(TObjectDictionary)
    private
        M_DefaultValue : V;

    public
        constructor Create(Defaultvalue : V);
        destructor Destroy; reintroduce;
        function GetDefaultValue : V;
        function TryGetValue(const Key: K; out Value: V): Boolean;
        function GetValueOf(const Key: K) : V;
    end;

implementation

//
// Contructor and destructor
//
constructor TDefaultDictonary.Create(Defaultvalue : V);
begin
    inherited Create;

    M_DefaultValue := Defaultvalue;
end;

destructor TDefaultDictonary.Destroy;
begin
    inherited Destroy;
end;

//
// Get the default Value
//
function TDefaultDictonary.GetDefaultValue : V;
begin
    Result := M_DefaultValue;
end;


//
// Try to get a value from the dictionary for the given key.
//
// If the value is found then "Value" holds it and the function returns true.
// If the value is not found then "Value" holds the default value and the
// function returns false.
//
function TDefaultDictonary.TryGetValue(const Key: K; out Value: V): Boolean;
var
    IsKeyFound : boolean;
    DictVal : V;

begin
    IsKeyFound := inherited TryGetValue(Key, DictVal);
    if not IsKeyFound then begin
        DictVal := M_DefaultValue;
    end;

   //Outputs:
    Value := DictVal;
    Result := IsKeyFound;
end;


//
// Get a value from the dictionary for the given key.
//
// If the value is found then the function returns it.
// If the value is not found the function returns the default value.
//
function TDefaultDictonary.GetValueOf(const Key: K) : V;
var
    DictVal : V;

begin
    TryGetValue(Key, DictVal);

    Result := DictVal;
end;

測試是:

unit Test_Utils;
{
    Test the TDefaultDictionary functionality
}

interface

uses
    Sysutils, Math, TestFramework, Util;

type

    TestUtil = class(TTestCase)

    public
        procedure SetUp; override;
        procedure TearDown; override;

    published
        procedure TestDefaultDictionaryGetDefaultResponse;
        procedure TestDefaultDictionaryExistingKey;
        procedure TestDefaultDictionaryNotExistingKey;

    end;


implementation


procedure TestUtil.SetUp;
begin
end;

procedure TestUtil.TearDown;
begin
end;


procedure TestUtil.TestDefaultDictionaryGetDefaultResponse;
var
    dd : TDefaultDictonary;

begin
    dd := TDefaultDictonary.Create('Default response');
    checkEquals('Default response', dd.GetDefaultValue);

    dd.Free;
end;

procedure TestUtil.TestDefaultDictionaryExistingKey;
var
    dd : TDefaultDictonary;
    outVal : string;
    isKeyFound : boolean;

begin
    dd := TDefaultDictonary.Create('Default response');
    dd.Add(1, 'My one');

    checkEquals(1, dd.Count,
        'One element as count');

    isKeyFound := dd.TryGetValue(1, outVal);
    check(isKeyFound,
        'Key not found by TryGetValue');

    checkEquals('My one', outVal,
        'Value given by TryGetValue');  

    checkEquals('My one', dd[1],
        'Value given by indexing as array');

    dd.Free;
end;


procedure TestUtil.TestDefaultDictionaryNotExistingKey;
var
    dd : TDefaultDictonary;
    outVal : string;
    isKeyFound : boolean;

begin
    dd := TDefaultDictonary.Create('Default response');
    dd.Add(1, 'one');

    isKeyFound := dd.TryGetValue(2, outVal);
    check(not isKeyFound,
        'Key should not be found by TryGetValue');

    checkEquals('Default response', outVal,
        'Default Value given by TryGetValue');

    checkEquals('Default response', dd.GetValueOf(2),
        'Default Value given by indexing as array');

    //
   //It is possible to oveload the indexer operator?
   //Please review or delete me !
    //
    //checkEquals('Default response', dd[2],
   //       'Value given by indexing as array');
    //

    dd.Free;
end;


initialization
    RegisterTest(TestUtil.Suite);
end.

這遠非完整。我想有索引操作員的工作也(見最後的測試)。這有可能嗎?還應該實施什麽?

這個實現是否泄漏了M_DefaultValue(我是Delphi的新手)。我不能在析構函數中做一些M_DefaultValue.Free(由於構造函數約束而不是那麽靈活)這裏可以做什麽?

提前致謝,

弗朗西斯

最佳答案

在自己編寫所有這些代碼之前,您可能需要查看 DeHL庫中的泛型類。

它支持這個:

定義支持的類型支持概念   一組默認的“支持類”   每個內置的Delphi類型(用作   集合中的默認值)。自定義“類型   支持“可以註冊課程   您的自定義數據類型。

--jeroen

轉載註明原文: Delphi Generics>具有默認值的字典