Click here to Skip to main content
15,907,001 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello, what is the difference between the following ways to instantiate my own class.

Case a)
C#
AnotherClass
{
  MyClass _myClass {get; set} = new();
}

In Case a) I also wonder how I can hand over parameters to the constructor,
when they do not yet exist at the time MyClass is instantiated.

Case b)
C#
AnotherClass
{
  MyClass _myClass {get;set;}
}

Case c)
C#
AnotherClass
{
  MyClass _myClass = new();
}

Case d)
C#
AnotherClass
{
  MyClass _myClass;
}


What I have tried:

Case a) worked fine and I see all properties of MyClass in the UI, whereas in the other cases b) to d) this is not the case.

This code is part of a 3rd party dll that uses the UI of the main app.
Posted
Updated 13-May-24 6:40am
v4

The only way to create an instance of a class is to "new it up". If you're not using new, you're not creating an instance of a class.

Case A creates an instance of MyClass and assigns it to the property _myclass of AnotherClass. Since class members are private by default, only the code in AnotherClass can see this property.

Case B only defines a property called _myClass that CAN HOLD an instance of MyClass. It does not create an instance of any class.

As a side, that code won't even compile. It should be
C#
AnotherClass
{
  MyClass _myClass { get; set; }
}

Case C creates an instance of MyClass and assigns it to a variable called _myClass. This variable is only accessible by code in the AnotherClass class.

Case D doesn't do anything except declare a variable that CAN HOLD an instance of MyClass, but there is no instance created by this code.


Passing paramters to a class constructor requires you to define a constructor in the class that takes parameters.
C#
public MyClass
{
    public MyClass()
    {
        // Parameterless constructor. Can be used by the class to initialize
        // any value data required by an instance of this class but has no
        // dependency on any outside data.
    }

    public MyClass(string value)
    {
        // Takes a string to be used to initialize data when an instance of
        // this class is created.
    }
    
    ...
}


To create an instance of the class that needs the string:
C#
MyClass _instance = new MyClass("some string value");

// or in newer C# versions:
MyClass _instance = new("some string value");

Quote:
In Case a) I also wonder how I can hand over parameters to the constructor,
when they do not yet exist at the time MyClass is instantiated.

If you don't have the data to pass to the constructor of MyClass before you create an instance of the class, you can't pass what doesn't exist now, can you?

The way around that would be to write your MyClass code to accept data through properties that can be set and properly maintain whatever state MyClass it's managing without having that data passed in via the constructor. The caller would have to set various properties on the MyClass instance whenever it gets the data it needs to pass in.
 
Share this answer
 
v3
C#
AnotherClass { MyClass _myClass {get; set} = new(); }
This is a property declaration with an auto-implemented property initialiser. _myClass is a property of type MyClass and it's initialised with a new instance of MyClass when AnotherClass is instantiated.


C#
AnotherClass { MyClass _myClass = {get;set;} }
This is not valid C#. It looks like you are trying to declare a property. It should look like this MyClass _myClass { get; set; }


C#
AnotherClass { MyClass _myClass = new(); }
This is a field declaration. _myClass is a field of type MyClass and it's initialised with a new instance of MyClass when AnotherClass is instantiated

Fields and properties typically have different access modifiers in C#.


C#
AnotherClass { MyClass _myClass; }
This is a field declaration without initialisation. _myClass is a field of type MyClass, but it's not initialised, so its value will be null until it's explicitly set.


Essentially your question is about fields vs. properties and instantiation at the time of declaration (or not).

Fields are typically used for internal use while properties expose fields to the outside world.
Auto-implemented properties (like in the first example) are a shorthand syntax that automatically creates a private, anonymous backing field that can only be accessed through the property's get and set accessors.


With regards to your question and the clarification given in your comment below :
In Case a) I also wonder how I can hand over parameters to the constructor, when they do not yet exist at the time MyClass is instantiated.
That looks circular ? You seem to want to create an instance of MyClass that contains an instance of AnotherClass but AnotherClass also contains an instance of MyClass and since you are using the this keyword then it would seem that the 'two' instances of MyClass are actually one in the same. Are you trying to allow a nested class to use the properties, methods and functions of its parent? I would recommend that you ask a separate question detailing what you are trying to achieve and ask how you might go about it.

M
 
Share this answer
 
v2
Comments
AtaChris 13-May-24 12:48pm    
Assume MyClass looks like as follows:

public MyClass
{
public MyClass()
{
// Parameterless constructor. Can be used by the class to initialize
// any value data required by an instance of this class but has no
// dependency on any outside data.
}

public MyClass(AnotherClass instance)
{
// Should take the instance of another class to use its memberfunctions and properties

}

...
}

And I would like to instantiate it as follows:

AnotherClass
{
MyClass _myClass {get; set} = new(this);
}

In such a case the compiler would say:

The this keyword was found outside of a property, method, or constructor or
A field initializer cannot reference the non-static field, method, or property 'name'.
M-Badger 14-May-24 4:00am    
See modified answer
To add to what the others have said, part of the instantiation process (when you create an instance of a class) is a call to the constructor.
When you use new to create a class instance, the system does the following tasks in order:

1) Allocate a chunk of heap memory big enough to hold the class instance data.
2) Set all fields of the newly allocated memory to their default value: for example, a variable that contains a reference will be null, an integer will be zero and so forth.
3) The instance constructor is called passing a reference to the memory allocated as this*
4) Object initializers are applied if any are specified.

So there are two ways to pass "parameters" to a constructor: via a constructor with a matching signature; or via an object initializer. In practice, you could do both:
C#
public class Program
    {
    public static void Main()
        {
        MC mc = new MC(666) {Y = 333};
        Console.WriteLine($"{mc.X}:{mc.Y}");
        }
    }
public class MC
    {
    public int X {get; set;}
    public int Y {get; set;}
    public MC(int x) { X = x;}
    }
But that does look rather odd and should probably be avoided!

* Which constructor? Depends - a constructor is treated as a function, and the "calling rules" for a function are applied. See here: Expressions - C# language specification | Microsoft Learn[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900