DoIt
DoIt

Reputation: 3448

Add properties to a complex datatype dynamically

I am working on a class with some properties like below in C#

public class SummaryDto
    {
        public string Name { get; set; }
        public string  GenericName { get; set; }            
        public int Data2012 { get; set; }
        public int Data2013 { get; set; }
        public int Data2014 { get; set; }
        public int Data2015 { get; set; }
        public int Data2016 { get; set; }
        public int Data2017 { get; set; }        

    }

In the above class the properties Data2012, Data2013 and so on should be added dynamically based on the data in another object which just contains years in it. May I know a good way to do it?

Upvotes: 1

Views: 55

Answers (4)

user8930129
user8930129

Reputation:

public class SummaryDto
{
    public string Name { get; set; }
    public string  GenericName { get; set; }            
    public Dictionary<int, int> Data { get; } = new Dictionary<int, int>();
}

I tried just like what Patrick Hoffman said above. This should do it.

Upvotes: 0

John Wu
John Wu

Reputation: 52290

public class SummaryDto
{
    public string Name {get; set;};
    public string GenericName {get; set; }
    public Dictionary<int,int> Data {get; } = new Dictionry<int,int>();
}

And add data for a year like

void SetYear(int year, int n)
{
    var s = new SummaryDto();
    s.Data[year] = n;
}

If you don't want a list because you have some restriction on how data is returned, wrap the list in its own class:

class YearData 
{
    List<int, int> _data = new List<int, int>();

    public int GetYearData(int year)
    {
        AssertYearValid(year);
        return _data[year];
    }

    public void SetYearData(int year, int number)
    {
        AssertYearValid(year);
        AssertYearNumberValid(number);
        _data[year] = number;
    }

    private void AssertYearValid(int year)
    {
        if (year < 1900 || year > 2900)
        {
            throw new ArgumentException("Year is not valid.");
        }
    }
}


public class SummaryDto
{
    public string Name {get; set;};
    public string GenericName {get; set; }
    public YearData Data {get; } = new YearData();
}

and set with

var s = new SummaryDto();
s.SetYearData(2001, 100);

Upvotes: 2

Patrick Hofman
Patrick Hofman

Reputation: 157098

Use a dictionary instead:

public class SummaryDto
{
    public string Name { get; set; }
    public string  GenericName { get; set; }            
    public Dictionary<int, int> Data { get; } = new Dictionary<int, int>();
}

Then set the data like this:

summaryDto.Data[2017] = 1;

And read it like this:

int value = summaryDto.Data[2017];

Or if you are not sure there is an entry for that year:

if (summaryDto.Data.TryGetValue(2017, out int value))
{
    // use value
}

Upvotes: 1

David
David

Reputation: 219047

It sounds like what you want is something like a Dictionary<K, V>. For example:

public Dictionary<int, int> Data { get; set; }

(And, of course, initialize it to something in the constructor.)

Then to "add a new year" you'd simply add it to the dictionary:

someObj.Data.Add(2017, someIntValue);

Basically, any time you have variables with an incrementing counter in their names, you probably want something like an array, list, dictionary, etc. instead.

Upvotes: 1

Related Questions