3

我有一堂课:

 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 将得到更新。我怎样才能做到这一点?谢谢!

4

3 回答 3

8

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

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

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

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

编辑 在评论中,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
    }
  }
}
于 2013-08-25T16:09:55.610 回答
1

所以我完全同意@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-08-25T16:51:35.050 回答
1

如果CustomClass1CustomClass2都来自CustomClassand 你想简单地设置 的值targetFieldName,你需要做的就是替换List<T>IEnumerable<T>

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

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.
于 2013-08-25T16:16:21.987 回答