0

I currently have to load some properties in a List like this:

        List<TestClass> test = new List<TestClass>(); // Loaded with data

        // Get calculated values back as double[]
        double[] calculatedValues = CalculateValue(test);

        // Add the calculated values to the List<TestClass> test object
        for (int i = 0; i < test.Count; i++)
        {
            test[i].Value = calculatedValues[i];
        }


    public int[] CalculateValue(List<TestClass> testClass)
    {
        int[] output = int[testClass.Count];
        // Some calculation
        return output;
    }


    public class TestClass
    {
        public string Name { get; set; }
        public int Value { get; set; }
    }

What I really would like to do is something like this:

    public static List<TestClass> CalculateValue(List<TestClass> testClass, string property)
    {
        double[] output = double[testClass.Count];
        // Some calculation
        // output to testClass

        // like:
        // testClass.property = output
        // Would then be like: testClass.Value = output
        return testClass;
    }

I would like to tell my method which property it should be added to. Is it possible in some way?

EDIT: Lets say I have Value2, Value3, Value4 etc. in my TestClass. Then I can not hardcode my CalculateValue method to always add to the "Value" property. Hope it makes sense

Hope it makes sense.

Best regards

user1281991
  • 763
  • 1
  • 12
  • 34
  • 2
    What is wrong with your current code? – Patrick Hofman Jan 13 '15 at 08:04
  • Lets say in my TestClass i have 10 properties that needs to be calculated. I would have to copy+paste the first codepart 10 times. I would be alot nicer with the bottom codepart, where I could just tell the method, which property the calculated values should be added to. – user1281991 Jan 13 '15 at 08:07
  • Then use a `Dictionary`. – Patrick Hofman Jan 13 '15 at 08:08
  • 2
    Why aren't you just setting the `Value` in the `CalculateValue` method? It doesn't look like there's a reason to fill it into a different array first, and then copy the values over. – Luaan Jan 13 '15 at 08:08
  • @user1281991 You see, that information changes this question tremendously :) For one, it's probably better fit for Code Review, rather than StackOverflow :) – Luaan Jan 13 '15 at 08:09
  • Because I need it to be generic. Lets say I have Value2, Value3, Value4 etc. in my TestClass. Then I can not hardcode my CalculateValue method to always add to the "Value" property. Hope it makes sense – user1281991 Jan 13 '15 at 08:10
  • Not sure why no one has mentioned reflection yet, Set the property value using the name of the property sounds like what you're after; see [here](http://stackoverflow.com/questions/7718792/can-i-set-a-property-value-with-reflection) – James Jan 13 '15 at 08:11
  • @JamesBarrass: there's no need for reflection here, since OP knows all properties at compile-time. A delegate to set property value will be enough. – Dennis Jan 13 '15 at 08:16
  • @Dennis Yeah, that makes sense, I was reading the preferred method signature a bit too literally – James Jan 13 '15 at 08:21

3 Answers3

1

You can use a delegate for storing the value in a property:

List<TestClass> test = new List<TestClass>(); // Loaded with data

// Get calculated values and store in list items
CalculateValue(test, (t, i) => t.Value = i);


public void CalculateValue(List<TestClass> testClass, Action<TextClass, int> store)
{
    int[] output = int[testClass.Count];
    // Some calculation
    for (int i = 0; i < output.Length; i++) {
      store(testClass[i], output[i]);
    }
}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0

I think you are look for DynamicObject. With DynamicObject you can write a general dynamic class, to which contains all properties in a Dictionary or something similar. With the methods TryGetMember and TrySetMember you can access the properties.

EDIT MSDN-Example:

// The class derived from DynamicObject.
public class DynamicDictionary : DynamicObject
{
    // The inner dictionary.
    Dictionary<string, object> dictionary
        = new Dictionary<string, object>();

    // This property returns the number of elements
    // in the inner dictionary.
    public int Count
    {
        get
        {
            return dictionary.Count;
        }
    }

    // If you try to get a value of a property 
    // not defined in the class, this method is called.
    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        // Converting the property name to lowercase
        // so that property names become case-insensitive.
        string name = binder.Name.ToLower();

        // If the property name is found in a dictionary,
        // set the result parameter to the property value and return true.
        // Otherwise, return false.
        return dictionary.TryGetValue(name, out result);
    }

    // If you try to set a value of a property that is
    // not defined in the class, this method is called.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        // Converting the property name to lowercase
        // so that property names become case-insensitive.
        dictionary[binder.Name.ToLower()] = value;

        // You can always add a value to a dictionary,
        // so this method always returns true.
        return true;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Creating a dynamic dictionary.
        dynamic person = new DynamicDictionary();

        // Adding new dynamic properties. 
        // The TrySetMember method is called.
        person.FirstName = "Ellen";
        person.LastName = "Adams";

        // Getting values of the dynamic properties.
        // The TryGetMember method is called.
        // Note that property names are case-insensitive.
        Console.WriteLine(person.firstname + " " + person.lastname);

        // Getting the value of the Count property.
        // The TryGetMember is not called, 
        // because the property is defined in the class.
        Console.WriteLine(
            "Number of dynamic properties:" + person.Count);

        // The following statement throws an exception at run time.
        // There is no "address" property,
        // so the TryGetMember method returns false and this causes a
        // RuntimeBinderException.
        // Console.WriteLine(person.address);
    }
}
BendEg
  • 20,098
  • 17
  • 57
  • 131
0

Why don't you use a Dictionary?

public class TestClass
{
    Dictionary<string,double> values = new Dictionary<string,double>

    public Dictionary<string,double> Values {get {return this.values; }}
    public string Name {get;set;}
}

TestClass testClass = new TestClass();
testClass.Values["Value1"] = 5.5;
quadroid
  • 8,444
  • 6
  • 49
  • 82