-2
class Program
{
    public  static void Main(string[] args)
    {
       

        Car c1 ;

        // c1's data
        c1.Brand = "Bugatti";
        c1.Model = "Bugatti Veyron EB 16.4";
        c1.Color = "Gray";

       

        // c1's data
     

        // Displaying the values
        Console.WriteLine(//"Name of brand: " + c1.Brand +
                          "\nModel name: " + c1.Model +
                          "\nColor of car: " + c1.Color);


        Console.ReadLine();
    }

}

public struct Car
{

    // Declaring different data types
    public string Brand { get; set; }
    public string Model;
    public string Color;
}

c1.Brand ="Bugatti" // giving compilation error - use of unassigned local variable 'c1' //local variable might not be initialized before accessing but c.Model or c1.Color is not throwing error.

  • Does this answer your question? [Why did I get the compile error "Use of unassigned local variable"?](https://stackoverflow.com/questions/9233000/why-did-i-get-the-compile-error-use-of-unassigned-local-variable) – gunr2171 Apr 27 '22 at 04:14
  • @gunr2171, I don't think it does. The question being asked here is why setting a property on an uninitialised value-type variable is flagged but setting a field is not. I tested the example code provided and can confirm the difference. For a class, all three assignments are flagged, as you'd expect. It does seem odd as I'm not sure why the property assignment would cause an issue. I guess it has something to do with how value-type variables are initialised but I don't know the actual explanation. – John Apr 27 '22 at 04:37
  • This may help: [How to perform struct inline initialization in C#?](https://stackoverflow.com/questions/4420094/how-to-perform-struct-inline-initialization-in-c). – NightOwl888 Apr 27 '22 at 05:31
  • Since values on the stack are not initialised. The compiler has to prove that every field in the struct is assigned before it is read. `Brand { set {...} }` is a method. You could write code to do anything, which means that the compiler has no idea what it does. Or at least it is too hard for the compiler to prove that it is safe to call it. So calling it is not allowed until the fields have been assigned. – Jeremy Lakeman Apr 27 '22 at 06:36

1 Answers1

1

As per the documentation:

Because structure types have value semantics, we recommend you to define immutable structure types.

Option 1

If your Car type's properties don't need to change at runtime, they should not have any public setters. You can simplify population of a new Car by adding a constructor or by using one of the other options described in the docs.

static class Program
{
    static void Main(string[] args)
    {
        Car c1 = new Car(
            // c1's data
            brand: "Bugatti",
            model: "Bugatti Veyron EB 16.4",
            color: "Gray");

        // c1's data

        // Displaying the values
        Console.WriteLine(//"Name of brand: " + c1.Brand +
                          "\nModel name: " + c1.Model +
                          "\nColor of car: " + c1.Color);
        Console.ReadLine();
    }
}


public struct Car
{
    public Car(string brand, string model, string color)
    {
        Brand = brand ?? throw new ArgumentNullException(nameof(brand));
        Model = model ?? throw new ArgumentNullException(nameof(model));
        Color = color ?? throw new ArgumentNullException(nameof(color));
    }

    // Declaring different data types
    public string Brand { get;}
    public string Model { get; }
    public string Color { get; }
}

Option 2

Use a class instead of a struct.

    static void Main(string[] args)
    {
        Car c1 = new Car(
            // c1's data
            model: "Bugatti Veyron EB 16.4",
            color: "Gray")
        { Brand = "Bugatti" };

        // c1's data

        // Displaying the values
        Console.WriteLine(//"Name of brand: " + c1.Brand +
                          "\nModel name: " + c1.Model +
                          "\nColor of car: " + c1.Color);
        Console.ReadLine();
    }
}


public class Car
{
    public Car(string model, string color)
    {
        Model = model ?? throw new ArgumentNullException(nameof(model));
        Color = color ?? throw new ArgumentNullException(nameof(color));
    }

    // Declaring different data types
    public string Brand { get; set; }
    public string Model { get; }
    public string Color { get; }
}

Since one of the main benefits of using struct is to allocate fixed sizes of data on the stack (using stackalloc) and you are using string properties (which are not a fixed size), the most sensible option is to use a class for this scenario. Whether you actually need a constructor, use property setters, or logical defaults depends on whether your application will deal with the values if they are null and/or default.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212