【问题标题】:dynamically work with different classes动态处理不同的类
【发布时间】:2013-08-28 03:57:43
【问题描述】:

我有一堂课:

 public class Test1
 {
     public void assignData(List<CustomClass> customData, string targetFieldName)
     {             
         for(int i=0; i<customData.Count; i++)
         {
             if(customData[i].targetFieldName)
             {
                 customData[i].targetFieldName = newValue;
             }   
         }
     }
 }

 List<customClass1> list1;
 List<customClass2> list2;

customClass1 和 customClass2 完全不同,但它们共享相同的字段“dateAdded”。我希望能够调用 Test1.assignData(list1, "dateAdded") 和 Test1.assignData(list2, "dateAdded")。并且 list1 和 list2 将得到更新。我怎样才能做到这一点?谢谢!

【问题讨论】:

  • customclass1 和 2 是否从 customclass 派生?
  • 如果你真的想放弃强类型并传递一个属性名称来分配,那么我认为你正在寻找这样的东西:stackoverflow.com/questions/1089123/…

标签: c# list class


【解决方案1】:

最好的方法是拥有一个他们都实现的通用接口,将dateAdded字段作为属性公开

interface ICustomClass {
  DateTime dateAdded { get; set; }
}

然后两个类都可以实现该接口,您可以更改函数以使用该接口

public void assignData(IEnumerable<ICustomClass> enumerable) {
  foreach (var customData in enumerable) {
    customData.dateAdded = newValue;
  }
}

编辑 在 cmets 中,OP 表示他们希望对任何列表进行此更新,而不管界面如何。在这种情况下,可能最好的方法是使用dynamic

public void assignData(IEnumerable<object> enumerable) {
  foreach (dynamic customData in enumerable) {
    try { 
      customData.dateAdded = newValue;
    } catch { 
      // Object doesn't have dateAdded so just move on
    }
  }
}

【讨论】:

  • 谢谢!如果我只想阅读它,我仍然需要实现接口怎么办?有没有办法做到这一点?
  • @user2320462 你总是可以使用dynamic 或反射来避免接口。一般来说,除非有令人信服的理由,否则我会避免使用它们并从界面开始
  • @user2320462:您可以在您的界面中使用get 访问器。
  • newValue 来自哪里 - 缺少参数?
  • @DerekW 未知,原始问题只有 newValue 没有任何上下文。我只是假设它是 OP 从问题中省略的字段
【解决方案2】:

如果 CustomClass1CustomClass2都派生自 CustomClass 并且您想简单地设置 targetFieldName 的值,您只需将 List&lt;T&gt; 替换为 IEnumerable&lt;T&gt;

确保公共字段位于基类中,以便可以访问它而不必担心派生实现。

public void assignData(List<CustomClass> customData, string targetFieldName)

public void assignData(IEnumerable<CustomClass> customData,
                                                string targetFieldName)

由于covariance,您可以为这两个列表调用它。简单的例子 -

IEnumerable<object> list = new List<string>(); // This will work

List<object> list = new List<string>(); // This won't compile.

【讨论】:

    【解决方案3】:

    所以我完全同意@JaredPar 的观点,这听起来像是您需要一个通用接口,但动态是可能的。

    请注意,如果 DateAdded 不存在,此示例代码将无法正常运行

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using NUnit.Framework;
    
    namespace dynamics_test
    {
        class CustomOne
        {
            public string NotInCustomTwo { get; set; }
            public DateTime DateAdded { get; set; }
        }
    
        class CustomTwo
        {
            public string NotInCustomOne { get; set; }
            public DateTime DateAdded { get; set; }
        }
    
    
        [TestFixture]
        public class TestDynamics
        {
            private List<CustomOne> _customOnes;
            private List<CustomTwo> _customTwos;
    
            [SetUp]
            public void Setup()
            {
                this._customOnes = new List<CustomOne>()
                    {
                        new CustomOne {DateAdded = DateTime.Now.AddDays(1), NotInCustomTwo = "some value"},
                        new CustomOne {DateAdded = DateTime.Now, NotInCustomTwo = "some value"}
                    };
                this._customTwos = new List<CustomTwo>()
                    {
                        new CustomTwo {DateAdded = DateTime.Now.AddDays(1), NotInCustomOne = "some value"},
                        new CustomTwo {DateAdded = DateTime.Now, NotInCustomOne = "some value"}
                    };
            }
    
            [Test]
            public void DynamicsAllowBadThingsMkay()
            {
                var dynamics = _customOnes.Cast<dynamic>().ToList();
                dynamics.AddRange(_customTwos);
                Assert.AreEqual(2, dynamics.Count(d=>d.DateAdded.Date == DateTime.Now.Date));
                foreach (var thing in dynamics)
                {
                    Console.WriteLine(thing.DateAdded);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-12-01
      • 2015-11-05
      • 2019-03-12
      • 2011-06-19
      • 2011-02-03
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      相关资源
      最近更新 更多