2016-07-07 65 views
0

我有一個Dictionary,它將枚舉值作爲鍵並返回一個對象作爲值。對象構造函數涉及調用需要很長時間並消耗大量內存的方法。現在,字典中的每個可能的對象都會被創建,即使只需要一個對象。有沒有辦法只創建鍵指定的對象?Make對象的字典只創建指定鍵的對象

private DataPreparer SetUpOuDataPreparer() 
{ 
    Scope = _activeDirectoryScope.Context; 
    var activeDirectorySearcher = new ActiveDirectorySearcher(
     _activeDirectoryScope); 
    var ouDataPreparers = new Dictionary<QueryType, DataPreparer> 
    { 
     [OuComputers] = new DataPreparer 
     { 
      Data = activeDirectorySearcher.GetOuComputerPrincipals(), 
      Attributes = DefaultComputerAttributes 
     }, 
     [OuGroups] = new DataPreparer 
     { 
      Data = activeDirectorySearcher.GetOuGroupPrincipals(
       CancellationToken), 
      Attributes = DefaultGroupAttributes 
     }, 
     [OuUsers] = new DataPreparer 
     { 
      Data = activeDirectorySearcher.GetOuUserPrincipals(), 
      Attributes = DefaultUserAttributes 
     }, 
     [OuUsersDirectReports] = new DataPreparer 
     { 
      Data = activeDirectorySearcher.GetOuUsersDirectReports(
       CancellationToken), 
      Attributes = DefaultUserDirectReportsAttributes 
     }, 
     [OuUsersGroups] = new DataPreparer 
     { 
      Data = activeDirectorySearcher.GetOuUsersGroups(
       CancellationToken), 
      Attributes = DefaultUserGroupsAttributes 
     } 
    }; 
    return ouDataPreparers[QueryType]; 
} 

也就是說方法創建所有五個DataPreparer S,其中的每一個具有在ActiveDirectorySearcher昂貴的方法調用。我想以某種方式只創建由QueryType密鑰指定的DataPreparer,最好不使用switchif/else。爲了更好的格式化/風格,我將其從那些更改爲Dictionary

+0

爲什麼要使用字典呢?爲什麼不只是一個帶有switch語句的工廠方法方法? –

+0

@AntP我在問題中提到我想避免切換,如果出於文體原因。 –

+0

我不確定他們是什麼「風格的原因」,但創建了一個你只需要一個對象的集合,因爲這個工作的正確工具看起來不太漂亮,這對我來說似乎有點落後。 –

回答

1

您可以更改的類型是Func<DataPreparer>所以你會得到一個值的工廠,只是後來調用它:

var ouDataPreparers = new Dictionary<QueryType, Func<DataPreparer>> 
{ 
    [OuComputers] =() => new DataPreparer 
    { 
     Data = activeDirectorySearcher.GetOuComputerPrincipals(), 
     Attributes = DefaultComputerAttributes 
    }, 

    return ouDataPreparers[QueryType](); 
} 

以這樣的方式,對象被創建的每個您的查詢的時間。

如果你想創建它一次,並保持相同的情況下像一個單身,你可以使用Lazy<DataPreparer>

var ouDataPreparers = new Dictionary<QueryType, Lazy<DataPreparer>> 
{ 
    [OuComputers] = new Lazy<DataPreparer>(() => new DataPreparer 
    { 
     Data = activeDirectorySearcher.GetOuComputerPrincipals(), 
     Attributes = DefaultComputerAttributes 
    }), 

    return ouDataPreparers[QueryType].Value; 
} 
+0

這兩個選項都會導致警告「隱式捕獲的閉包:this」。思考? –

+0

我想這是'DefaultComputerAttributes',它可能是lambda表達式中使用的對象的變量。 –

+0

所有賦給'Attributes'的值都是'static readonly Array's。這個警告也只出現在'OuUsers'和'OuComputers'條目中(只有兩個不帶'CancellationToken'參數)。 –

6

我會考慮在您的DataPreparer類中使用Lazy<T>作爲您的Data屬性。這樣,它只會在實際需要時調用activeDirectorySearcher.GetOuGroupPrincipals,而不是在創建時一次。