I'm not sure I follow your concern. In order to use an object it must first be created. That is what the constructor does. A constructor always runs before the caller has access to any of the data to be set. Here's the rough "flow" of object initialization. Given:
(1) var obj = new SomeClass();
(2) obj.Property1 = "Value";
And the general flow for line 1. Note I'm leaving out things not relevant to this example.
-
new
is executed and memory is allocated for the object. - All field initializers defined within the type are executed.
- If the type derives from a class then the base class's constructor runs (going all the way back to the root of the type hierarchy).
- The type's constructor executes.
- The newly created object is used as the value of the
new
expression. - The assignment sets
obj
to the newly created object.
Line 1 is complete and then we move to line 2.
- Assign the given value to the property of the object.
Note that if you use object initializer syntax then the compiler simply rewrites your code to the above equivalent.
Thus the only values accessible within a constructor are the fields that may or may not have been initialized by initializer expressions and the parameters to the constructor. If you need to set a field/property based upon some value outside the type then you would need to pass it as a parameter to the constructor. For example suppose SomeClass
needs to know the Id of the object it is working against AND that value won't change for the life of the instance. In that case it would need to be a parameter to the constructor.
public class SomeClass
{
public SomeClass ( int id )
{
Id = id;
}
public int Id { get; }
}
var obj = new SomeClass(1);
Constructors should just set fields/properties of an object. If data is needed to do that then use parameters. Constructors should not call methods that may be virtual, need to do extensive work or will likely fail as that makes it harder to work with the type. In your case if RefreshData
is simply updating fields based upon the parameters to the constructor then go ahead and call it within the constructor. However if RefreshData
is going to do something like query a database or make an API call then it does not belong in the constructor. Ideally have the caller "refresh" the data when it is ready. In other cases you can defer the refresh until you actually need the data which should be some time after the constructor is run.