3

I have a class:

 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 and customClass2 are completely different, but they share the same field 'dateAdded'. I want to be able to call Test1.assignData(list1, "dateAdded") and Test1.assignData(list2, "dateAdded"). and the list1 and list2 will get updated. How can I do that? Thanks!

2
  • 2
    do customclass1 and 2 derive from customclass ? Commented Aug 25, 2013 at 16:08
  • If you really want to let go of strong typing and pass a property name to assign, then I think you're looking for something like this: stackoverflow.com/questions/1089123/… Commented Aug 25, 2013 at 16:54

3 Answers 3

8

The best way to do this is to have a common interface that they both implement which exposes the dateAdded field as a property

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

Then both classes can implement that interface and you can change the function to use that interface

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

EDIT In the comments the OP stated their desire to make this update to any list irrespective of the interface. In that case the likely best course is to use 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
    }
  }
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks! What if I just want to read it I still have to implement the interface? is there a way of doing it without?
@user2320462 you can always use dynamic or reflection to avoid an interface. In general though I would avoid them unless there was a compelling reason and start with an interface
@user2320462: you can just have a get accessor in your interface.
Where is newValue coming from - missing parameter?
@DerekW unknown, the original question just has newValue without any context. I just assumed it was a field the OP omitted from the question
|
1

If CustomClass1 and CustomClass2both deriving from CustomClass and you want to simply set value of targetFieldName , all you need to do is replace List<T> with IEnumerable<T>.

Make sure the common field is in base class so that it can be accessed without worrying about the derived implementation.

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

with

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

With this you can call it for both lists because of covariance. Simple example -

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

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

Comments

1

So I totally agree with @JaredPar that this sounds like you need a common interface but it is possible with dynamics.

Note that this example code doesn't behave properly if DateAdded isn't present

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.