Ian
Ian

Reputation: 55

C#: Set property in constructor by method

I'm beginning to understand C# and OOP, and have a problem that I can't seem to get around. I have a class called DataSet that should hold several properties (in the form of System.Collections.Generic.Dictionary objects). Within the class I have methods that load data from a database and these methods should be used to initialize the DataSet. Basically, I want the DataSet object to have all properties set, when I instantiate it from the Main method.

What I have is the following (leaving out the details):

public class DataSet
{
    public IDictionary<string, MyClass1> Property1 { get; set; };
    public IDictionary<string, MyClass2> Property2 { get; set; };
    public IDictioanry<string, MyClass3> Property3 { get; set; };

    public DataSet()
    {
            Property1 = new Dictionary<string, MyClass1>();
            Property2 = new Dictionary<string, MyClass2>();
            Property3 = new Dictionary<string, MyClass3>();
        // Set Property1
        // Set Property2
        // Set Property3 (can only be done when Property1 is known)
    }

    private void GetProperty1(/* something? */)
    {
        // Loads the data from a database.
    }

    private static Dictionary<string, MyClass1> GetProperty1Alternative(DataSet dataSet)
    {
        // Same thing but static, so needs instance ref.
    }

    // Similarly for Property2 and Property3
}

What I would like is to have the properties set in the constructor. My questions are basically:

  1. Is what I am doing at all the right way to do it?
  2. If yes, should I make my methods static (and pass an instance by reference to the methods), which would require the class DataSet to be static (and all its properties) or is there a way to do what I am doing without making DataSet static?
  3. An important issue is that Property3 can only be set once Property1 is known/set. I have no idea if that is possible...

Any help is greatly appreciated.

Upvotes: 4

Views: 4098

Answers (5)

David S.
David S.

Reputation: 6105

Is what I am doing at all the right way to do it?

You're not that far off. I think many people are confusing your Get functions to be the conventional 'getter', so you should rename it.

If yes, should I make my methods static (and pass an instance by reference to the methods), which would require the class DataSet to be static (and all its properties) or is there a way to do what I am doing without making DataSet static?

You could make the methods actually loading the data static, and you don't need to pass an instance - you can just return the data. (I've changed thefunction name). It's fine to call a static method from the instance/constructor, but not the other way around.

public DataSet()
{
        Property1 = LoadProperty1();
        Property2 = LoadProperty2();
        Property3 = LoadProperty3();//can only be done when Property1 is known
}

private static Dictionary<string, MyClass1> LoadProperty1()
{
    // load data
}

An important issue is that Property3 can only be set once Property1 is known/set. I have no idea if that is possible...

As you see, this is solved in the above code.

Upvotes: 0

Daan
Daan

Reputation: 118

It seems to me you need to load your dictionary and then want to cache it. You can do this lazily in the property getter:

public class DataSet
{
    private IDictionary<string, MyClass> property;

    public IDictionary<string, MyClass> Property
    {
        if (property == null)
        {
            property = LoadProperty();
        }
        return property;
    }
}

or eagerly in the constructor:

public class DataSet
{
    public IDictionary<string, MyClass1> Property { get; private set; }    

    public DataSet()
    {
        Property = LoadProperty();
    }
}

Also, having this method doesn make much sense:

private static Dictionary<string, MyClass1> GetProperty1Alternative(DataSet dataSet)

Instead of calling this like so:

DataSet.GetProperty1Alternative(anInstance);

you can simply do this:

anIntance.Property;

Upvotes: 0

DasDave
DasDave

Reputation: 811

Why not add a public function e.g. LoadData() that could be called after your object has been constructed. This could load all your data in using the correct order. I suppose you could have call it in the constructor even. I would also follow the advice of Lukos and make some private member variables with public get properties.

Upvotes: 0

Alexandr
Alexandr

Reputation: 1460

You can use following code. It can solve you several issues.

public class DataSet
{
    private DataSet()
    {
    }

    public DataSet _instance = null;
    public static DataSet Instance
    {
       get{ if (_instance = null){_instance = new DataSet();}return _instance;}
    }


    private IDictionary<string, MyClass1> _property1 = null;
    public IDictionary<string, MyClass1> Property1
    {
        get
        {
           result = _property;
           if (result == null)
           {
             //read database
           } 
           return result;
        }
    }

Upvotes: 0

Lukos
Lukos

Reputation: 1852

There are a few issues in your code. You have made the properties public so it doesn't really make sense to also have GetProperty1. An alternative would be to make the dictionaries private variables instead then you can have:

public IDictionary<string,MyClass1> GetProperty1()
{
    if ( _property1 == null )
    {
        _property1 = LoadFromDatabase();
    }
    return _property1;
}

Likewise for property3, you can also check that proeprty1 is not null before you create and return it but you would also then need to decide what to do (automatically load property 1 first or otherwise return null for property3)

Upvotes: 2

Related Questions