通用接口
我正在设计一个应用程序,其中相似的实体位于两个具有不同类型集合的位置,如下所示。
模型:
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 & ViewModel 已同步。
I am designing an app where similar entities are in two places with different types of collection as following.
Model:
class PersonModel {
public string Name { get;set;}
public List<Address> Addresses { get;}
public List<OtherType> OtherTypes { get;}
}
Similar view model:
class PersonViewModel {
public string Name { get;set;}
public ObservableCollection<Address> Addresses { get; }
public ObservableCollection<OtherType> OtherTypes { get; }
}
To make both entities consistent, I thought use generic interface which ensure both implement all properties, so I created something like this:
public interface IPerson<T> where T: ICollection<T> {
string Name { get;set;}
T<Address> Addresses { get;}
T<OtherType> OtherTypes [ get; }
}
and classes will be
class PersonModel<List> {}
class personViewModel<ObservableCollection> {}
but compiler not ready to compile my interface. :(
Says, the type parameter "T" cannot be used with type argument.
Reason why I want this, i wanted to minimize type conversion from / to model & viewModel.
My viewModel will be like this,
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>(); }
}
}
Suggest me better way to have Model & ViewModel synchronized.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
ViewModel 的存在是为了为 View 提供数据。这意味着它应该根据视图的要求进行建模。通常,这些要求与模型的要求不同。这意味着,通常情况下,您的模型和视图模型不会同步,它们会有所不同。在您的方法中,ViewModel 没有添加任何值,可以删除。
要在 ViewModel 和 Model 之间进行映射,您可以使用 AutoMapper。
The ViewModel exists to provide data for the View. This means it should be modeled after the requirements of the View. Normally, these requirements are not the same as those for the Model. That means, that normally, your Model and your ViewModel won't be in sync, they will differ. In your approach the ViewModel is not adding any value and could be removed.
To map between the ViewModel and the Model you could use AutoMapper.
您的实现应如下所示:
您真的需要一个泛型类吗?
ObservableCollection
和List
都实现ICollection
,因此您可以在接口中将 Addresses 和 OtherTypes 声明为分别是ICollection
和
ICollection
。(什么是AddressView?)
Your implementations should look like the following:
Do you really need a generic class?
ObservableCollection<T>
andList<T>
both implementICollection<T>
so you might be able to declare Addresses and OtherTypes in your interface asICollection<Address>
andICollection<OtherType>
respectively.(what's AddressView?)
您不能以这种方式使用泛型。你可以尝试这样的事情
然后
You cannot use generics in that way. You can try something like this
And then
您对
IPerson
的通用约束是强制 T 必须实现 T 的ICollection
吗?这是无限递归的,这是不允许的。您也不能在泛型类型上指定泛型参数,因此不允许使用
T
,这是因为不知道
T
是泛型类型还是不是。您可以将您的界面更改为以下内容:
然后像这样使用它:
我认为这是获得您想要的方法的唯一真正方法。但我建议您的接口仅返回
ICollection
和
ICollection
。然后,您的模型/视图模型必须通过接口公开集合,但是没有什么可以阻止您分别将支持实现作为List
或ObservableCollection
。Your generic constraint on
IPerson
is enforcing that T must implement anICollection
of T? That's endlessly recursive which wouldn't be allowed.You also can't specify generic parameters on generic types, so
T<Address>
isn't allowed, this is because it is not known whetherT
is a generic type or not.You could change your interface to be the following:
Then use it like so:
I think that's the only real way to get the approach you want. But I would suggest that your interface merely returns
ICollection<Address>
andICollection<OtherType>
. Your model/viewmodel will then have to expose the collections through the interface, however there is nothing stopping you having the backing implementations asList
orObservableCollection
respectively.