【问题标题】:Convert <T> into ViewModel将 <T> 转换为 ViewModel
【发布时间】:2016-11-24 10:41:28
【问题描述】:

我想知道是否有可能以更通用的方式解决这个问题。

给出两个几乎相同的视图模型,区别在于命名(例如,公共字符串描述和公共字符串 ReviewDescription) 有一个比较函数是这样工作的:

   private bool CompareTask(Models.Task model, TaskViewModel data)
        {
            bool same = false;
                    same = (model.Description == data.Description); // more compare
            return same;
        }

问题:是否有可能 - 如果是,如何 - 将泛型用于视图模型,如下所示:

  private bool CompareTask<T>(Models.Task model, T data)

并创建一个 if 语句,如:

if (typeof(T) == typeof(TaskViewModel)){ ... }
else if (typeof(T) == typeof(TaskReviewModel)) { ... }

【问题讨论】:

    标签: c# generics type-conversion


    【解决方案1】:

    你为什么不用IEquatable&lt;T&gt;

    在您的视图模型模型中实现它:

    public class SomeViewModel : IEquatable<SomeModel>
    {
        bool IEquatable<SomeModel>.Equals(SomeModel model)
            => model != null && SomeProperty == model.SomeOtherProperty;
    }
    

    现在,你可以实现这个方法了:

    public bool AreEqual<T, S>(T a, S b)
         where T : class
         where S : class
    {
        IEquatable<S> equatableToB = a as IEquatable<S>;
    
        return equatableToB != null && equatableToB.Equals(b);
    }
    

    这种方法有一个明显的优势:模型或视图模型都可以等同于一个或多个类:

    public class SomeViewModel : IEquatable<SomeModel>, IEquatable<SomeOtherModel>
    {
        bool IEquatable<SomeModel>.Equals(SomeModel model)
            => model != null && SomeProperty = model.SomeOtherProperty;
    
    
        bool IEquatable<SomeOtherModel>.Equals(SomeOtherModel model)
            => model != null && SomeOtherProperty = model.EvenSomeOtherProperty;
    }
    

    【讨论】:

    • 谢谢大家,我会选择@Matías-Fidemraizer 解决方案。
    【解决方案2】:

    是的,这是可能的。最简单的方法是创建基础视图模型类:

    public abstract class ViewModelBase { .. }
    

    然后您可以添加一个通用方法,例如:

    ViewModelBase GetViewModel<T>() where T : ViewModelBase {
    
        // get or convert your viewmodel
        return (t) Convert.ChangeType(typeof(T), this.ViewModel);
    }
    

    【讨论】:

      【解决方案3】:

      您可以将BaseViewModel 作为 BaseClass 并以这种方式实现泛型方法:

       public class BaseViewModel
        {
           /// add members
        }
      
       public class TaskViewModel : BaseViewModel
       {
           /// add members
       }
      
       public class TaskReviewViewModel : BaseViewModel
       {
          /// add members
       }
      
      
        private bool CompareTask<T>(Models.Task model)
                  where T:BaseViewModel
        {
            var instance = Activator.CreateInstance<T>();
                  ....
        }
      

      【讨论】:

      • 我可以跟着你做var instance = Activator.CreateInstance&lt;T&gt;(); - 为什么,已经有一个T data 参数?
      • @PeterB 同意。没必要。
      【解决方案4】:

      如果您的多个 TaskModel 具有相同的签名,请使用您要比较的属性的接口。

      另一种方法是将 IEquatable 实现到您的其他模型并执行类似的操作

      public class Task
      {
      }
      
      public class TaskViewModel : IEquatable<Task>
      {
          public bool Equals(Task other)
          {
              throw new NotImplementedException();
          }
      }
      
      private bool CompareTask<T>(Task model, T data)
              where T : IEquatable<Task>
      
          {
              return data.Equals(model);
          }
      

      【讨论】:

        猜你喜欢
        • 2020-11-25
        • 1970-01-01
        • 1970-01-01
        • 2021-12-02
        • 1970-01-01
        • 2014-10-04
        • 2012-01-30
        • 1970-01-01
        相关资源
        最近更新 更多