2011-01-06 70 views
1

可以說我有以下的階層結構在我的數據訪問層:如何避免ref參數不允許類型變化?

interface IBehavior<in T> 
{ 
    void Load(T model); 
} 

class ModelManager<T> 
{ 
    ModelManager(IEnumerable<IBehavior<T>> behaviors) { ... } 

    void Load(T model) 
    { 
    foreach (var behavior in behaviors) { 
     behavior.Load(model) 
    } 
    } 
} 

這讓我有我的模型可以實現處理這些接口的各種接口,可重複使用的行爲:

interface IUnique { ... } 
class UniqueBehavior : IBehavior<IUnique> { ... } 

interface ITimestampable { ... } 
class TimestampableBehavior : IBehavior<ITimestampable> { ... } 

經理會很樂意接受這些,因爲在IBehavior<T>中存在矛盾。

class MyModel : IUnique, ITimestampable { ... } 

new ModelManager<MyModel>(new IBehavior<MyModel>[] { 
    new UniqueBehavior(), 
    new TimestampableBehavior() 
}); 

超。

但是現在,我想讓每個行爲都對實體應用一組LINQ過濾器。我的第一個想法是將這個方法添加到IBehavior<T>

void ApplyFilters<IEnumerable>(ref IEnumerable<T> models) 

...其中一個執行行爲將應用一組Where條款在其自由裁量權的枚舉。

但是,事實證明,ref parameters don't allow type variation。我努力尋找一種方法來實現這種功能,同時保持類型安全和接口的逆變性質。任何想法都表示讚賞。

+1

我期望`ApplyFilters`有簽名`IEnumerable ApplyFilters(IEnumerable models)' – Gabe 2011-01-06 14:29:31

+0

也不管用,它使T成爲返回類型。我記得都嘗試過,在我的用例中使用ref更有意義。這樣,如果行爲不想應用任何過濾器,則可以將該方法留空。 – 2011-01-06 14:38:11

回答

1

不知道這是否會在您的確切上下文中工作,但您是否嘗試過使ApplyFolders泛型本身?

void ApplyFolders<TEnum>(ref IEnumerable<TEnum> models) where TEnum : T; 
+0

這太瘋狂了,它的工作原理!謝謝,我自己也不會想到這件事。 – 2011-01-06 15:58:49

1

我會看看Ptr class。最近我一直在利用這個類來徹底地破解.NET放入ref關鍵字的所有限制,讓我對CLR出於某種原因感覺我沒有權利使用副作用對象。