2012-02-02 49 views
1

我正在設計一個應用程序,其中類似的實體在兩個地方有不同類型的集合,如下所示。通用接口

型號:

class PersonModel { 
    public string Name { get;set;} 
    public List<Address> Addresses { get;} 
    public List<OtherType> OtherTypes { get;} 
} 

類似的視圖模型:

class PersonViewModel { 
    public string Name { get;set;} 
    public ObservableCollection<Address> Addresses { get; } 
    public ObservableCollection<OtherType> OtherTypes { get; } 
} 

爲了使兩個實體一致,我想使用通用接口,保證都實現所有的屬性,所以我創造了這樣的事情:

public interface IPerson<T> where T: ICollection<T> { 
    string Name { get;set;} 
    T<Address> Addresses { get;} 
    T<OtherType> OtherTypes [ get; } 
} 

and classes will將

class PersonModel<List> {} 
class personViewModel<ObservableCollection> {} 

但編譯器沒有準備好編譯我的接口。 :( 說,類型參數「T」不能與類型參數一起使用。

原因,我想這一點,我想盡量減少類型轉換/到&視圖模型建模。

我的視圖模型將會怎樣對此,

class PersonViewModel<T> : IPerson<T> { 
    public PersonViewModel(IPerson model){ 
     this.Model = model; 
    } 
    internal PersonModel Entity { 
     get; set; 
    } 
    public string Name { 
     get{ return model.Name;} 
     set {model.Name = value;} 
    } 
    public T<Address> Addresses { 
     get { return model.Addresses.Cast<T>(); } 
    } 
} 

建議我更好的辦法,有型號&視圖模型同步。

+0

也許你應該只使用Automapper。 – CodesInChaos 2012-02-02 09:38:42

+0

我已經使用它,但團隊成員不喜歡它的大和嵌套實體 – hungryMind 2012-02-02 09:40:36

回答

0

你不能以這種方式使用泛型。你可以嘗試這樣的事情

public interface IPerson 
{ 
    string Name { get; set; } 
    ICollection<Address> Addresses { get; } 
    ICollection<OtherType> OtherTypes { get; } 
} 

public class OtherType { } 
public class Address { } 

然後

class PersonModel : IPerson 
{ 
    public PersonModel() 
    { 
     Addresses = new List<Address>(); 
     OtherTypes = new List<OtherType>(); 
    } 

    public string Name { get; set; } 
    public ICollection<Address> Addresses { get; private set; } 
    public ICollection<OtherType> OtherTypes { get; private set; } 
} 

class PersonViewModel : IPerson 
{ 
    public PersonViewModel() 
    { 
     Addresses = new ObservableCollection<Address>(); 
     OtherTypes = new ObservableCollection<OtherType>(); 
    } 

    public string Name { get; set; } 
    public ICollection<Address> Addresses { get; private set; } 
    public ICollection<OtherType> OtherTypes { get; private set; } 
} 
+0

,但這確實確保ViewModel – hungryMind 2012-02-02 09:49:04

+0

這是否工作? C#不允許協變返回類型。 – Lukazoid 2012-02-02 09:50:18

+0

@Lukazoid,是的,我搞砸了,並糾正了代碼。現在它可以工作。 – oleksii 2012-02-02 11:13:46

1

視圖模型存在,爲查看提供的數據,這意味着它應該是MOD在View的要求之後退出。通常情況下,這些要求與模型不同。這意味着,通常情況下,您的Model和您的ViewModel不會同步,它們會有所不同。在你的方法中,ViewModel沒有添加任何值,可以刪除。

要在ViewModel和Model之間進行映射,可以使用AutoMapper

1

你的實現應該如下所示:

class PersonModel : IPerson<List> {} 
class PersonViewModel : IPerson<ObservableCollection> {} 

你真的需要一個泛型類? ObservableCollection<T>List<T>都執行ICollection<T>,因此您可能能夠分別在您的接口中聲明地址和其他類型爲ICollection<Address>ICollection<OtherType>

(什麼是AddressView?)

+0

問題不是與類但接口,我的接口正在編譯。更改AddressView到地址 – hungryMind 2012-02-02 09:47:35

0

您對IPerson通用的限制被執行的是T必須實現T的ICollection?這是無法遞歸的,這是不允許的。

您也不能在通用類型上指定通用參數,因此不允許T<Address>,這是因爲不知道T是否是泛型類型。

你可以改變你的界面如下所示:

public interface IPerson<TAddressCol, TOtherCol> 
    where TAddressCol: ICollection<Address> 
    where TOtherCol : ICollection<OtherType> 
{ 
    string Name { get;set;} 
    TAddressCol Addresses { get;} 
    TAddressCol OtherTypes [ get; } 
} 

然後使用它像這樣:

class PersonModel<List<Address>, List<OtherType>> {} 
class personViewModel<ObservableCollection<Address>, ObservableCollection<OtherType>> {} 

我想這是得到你想要的方式的唯一途徑。但是我建議你的界面只返回ICollection<Address>ICollection<OtherType>。然後,您的模型/視圖模型將不得不通過界面展示集合,但是沒有任何東西阻止您分別獲得ListObservableCollection的支持實現。

+0

不,這只是一個例子。我的實體包含許多類型的列表。指定所有類型不是個好主意 – hungryMind 2012-02-02 10:50:36

+0

爲什麼你的界面不能返回'ICollection's?你的實現返回'ICollection's?那麼每個實現都可以返回'ICollection'的不同實現? – Lukazoid 2012-02-02 11:13:18

+0

有關我的意思,請參閱@ oleksii的答案,這就是我的願望。 – Lukazoid 2012-02-02 11:17:17