我正在设计一个应用程序,其中类似的实体位于两个地方,具有不同类型的集合,如下所示。
型号:
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; }
}
和课程将
class PersonModel<List> {}
class personViewModel<ObservableCollection> {}
但编译器还没准备好编译我的接口。 :( 说,类型参数“T”不能与类型参数一起使用。
为什么我想要这个,我想最小化从/到模型和类型的类型转换视图模型。
我的viewModel将是这样的,
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>(); }
}
}
建议我更好地使用Model&amp; amp; ViewModel已同步。
答案 0 :(得分:1)
ViewModel的存在是为View提供数据。这意味着它应该根据View的要求建模。通常,这些要求与模型的要求不同。这意味着,通常情况下,您的模型和ViewModel不会同步,它们会有所不同。在您的方法中,ViewModel不会添加任何值,可以删除。
要在ViewModel和模型之间进行映射,您可以使用AutoMapper。
答案 1 :(得分:1)
您的实施应如下所示:
class PersonModel : IPerson<List> {}
class PersonViewModel : IPerson<ObservableCollection> {}
你真的需要一个通用课吗? ObservableCollection<T>
和List<T>
都实施ICollection<T>
,因此您可以在界面中分别将地址和其他类型声明为ICollection<Address>
和ICollection<OtherType>
。
(什么是AddressView?)
答案 2 :(得分: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; }
}
答案 3 :(得分:0)
您对IPerson
的通用约束强制要求T必须实现ICollection
的T?这是无休止的递归,这是不允许的。
您也无法在泛型类型上指定泛型参数,因此不允许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>
。然后,您的model / viewmodel必须通过接口公开集合,但是没有什么能阻止您将支持实现分别设置为List
或ObservableCollection
。