通用接口

发布于 2025-01-01 11:12:28 字数 1423 浏览 7 评论 0原文

我正在设计一个应用程序,其中相似的实体位于两个具有不同类型集合的位置,如下所示。

模型:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

〆凄凉。 2025-01-08 11:12:28

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.

东京女 2025-01-08 11:12:28

您的实现应如下所示:

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

您真的需要一个泛型类吗? ObservableCollectionList 都实现 ICollection,因此您可以在接口中将 Addresses 和 OtherTypes 声明为分别是 ICollection

ICollection

(什么是AddressView?)

Your implementations should look like the following:

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

Do you really need a generic class? ObservableCollection<T> and List<T> both implement ICollection<T> so you might be able to declare Addresses and OtherTypes in your interface as ICollection<Address> and ICollection<OtherType> respectively.

(what's AddressView?)

赴月观长安 2025-01-08 11:12:28

您不能以这种方式使用泛型。你可以尝试这样的事情

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; }
}

You cannot use generics in that way. You can try something like this

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

public class OtherType { }
public class Address { }

And then

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; }
}
甜妞爱困 2025-01-08 11:12:28

您对 IPerson 的通用约束是强制 T 必须实现 T 的 ICollection 吗?这是无限递归的,这是不允许的。

您也不能在泛型类型上指定泛型参数,因此不允许使用 T

,这是因为不知道 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

ICollection。然后,您的模型/视图模型必须通过接口公开集合,但是没有什么可以阻止您分别将支持实现作为 ListObservableCollection

Your generic constraint on IPerson is enforcing that T must implement an ICollection 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 whether T is a generic type or not.

You could change your interface to be the following:

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

Then use it like so:

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

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> and ICollection<OtherType>. Your model/viewmodel will then have to expose the collections through the interface, however there is nothing stopping you having the backing implementations as List or ObservableCollection respectively.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文