Edward Tanguay
Edward Tanguay

Reputation: 193332

Is there a syntactic sugar C# property syntax to instantiate generic collections?

The following program will fail because Contracts is not instantiated.

Of course I can instantiate it in my constructor but if I have dozens of properties and/or multiple constructors I have to keep track of which are instantiated, etc.

And of course I could create large blocks for these properties with full gets and sets and private field variables, etc. But this gets messy as well.

Isn't there a way to automatically instantiate these collections with the nice C# property syntax?

using System;
using System.Collections.Generic;

namespace TestProperty232
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();
            customer.FirstName = "Jim";
            customer.LastName = "Smith";

            Contract contract = new Contract();
            contract.Title = "First Contract";

            customer.Contracts.Add(contract);

            Console.ReadLine();
        }
    }

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<Contract> Contracts { get; set; }

        public Customer()
        {
            //Contracts = new List<Contract>();
        }
    }

    public class Contract
    {
        public string Title { get; set; }
    }
}

Upvotes: 2

Views: 3874

Answers (7)

BillW
BillW

Reputation: 3435

Sugary or lemony : you decide : (VS 2010 beta 2, FrameWork 4)

    Customer customer = new Customer
    {
        FirstName = "Jim", 
        LastName = "Smith", 
        Contracts = new List<Contract> { new Contract { Title ="First Contract" } }
    };

Works fine with your existing class definitions, but feels awkward to read ?

best,

Upvotes: 1

Jon Comtois
Jon Comtois

Reputation: 1854

You could make Contracts not be an autoproperty:

private List<Contract> _contracts;
public List<Contract> Contracts
{
    get
    {
        if (_contracts == null)
        {
            _contracts = new List<Contract>();
        }
        return _contracts;
    }
    set
    {
        if (!_contracts.Equals(value))
        {
            _contracts = value;
        }
    }
}

That will allow you not to have to explicitly instantiate Contracts.

Upvotes: 0

Dan Hedges
Dan Hedges

Reputation: 136

Not sure what you are actually looking for, but you could tidy it up a bit like this...

using System;
using System.Collections.Generic;

namespace TestProperty232
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer() { 
                FirstName = "Jim",
                LastName = "Smith"
            };

            Contract contract = new Contract() { 
                Title = "First Contract"
            };

            customer.Contracts = new List<Contract>() { contract };

            Console.ReadLine();
        }
    }

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<Contract> Contracts { get; set; }

        public Customer()
        {
            //Contracts = new List<Contract>();
        }
    }

    public class Contract
    {
        public string Title { get; set; }
    }
}

Upvotes: 0

Joe
Joe

Reputation: 47629

Long answer: how's this?

using System.Collections.Generic;

namespace proto
{
    public class Customer
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

    }

    public class Contract
    {
        public List<Customer> Customers { get; set; }

        public string Title { get; set; }
    }

    public class ContractDemo
    {
        public Contract CreateDemoContract()
        {
            Contract newContract = new Contract
            {
                Title = "Contract Title", 
                Customers = new List<Customer>
                {
                    new Customer
                    {
                        FirstName = "First Name",
                        LastName = "Last Name"
                    },
                    new Customer
                    {
                        FirstName = "Other",
                        LastName = "Customer"
                    }
                }
            };

            return newContract;
        }

    }
}

Upvotes: 1

Mark Seemann
Mark Seemann

Reputation: 233192

There is no such syntactic sugar, but I'd like to point out a few things:

  • Collection properties should be read-only in any case.
  • If you have a lot of such properties in a single type, it's a strong symptom that you are violating the Single Responsibility Principle
  • If you have multiple constructors, you should always take great care that there's only one constructor that does the real work, and all other constructors delegate to that constructor. Alternatively you can delegate all constructor work to a private Initialize method.

Upvotes: 6

Maximilian Mayerl
Maximilian Mayerl

Reputation: 11357

No, there is no sugar. Instantiate them in your parameterless constructor and redirect all your other constructors there, so that it will always execute.

class MyClass
{
    //Many properties

    public MyClass()
    {
        //Initialize here
    }

    public MyClass(string str) : this()
    {
        //do other stuff here
    }
}

Upvotes: 5

Klaus Byskov Pedersen
Klaus Byskov Pedersen

Reputation: 120967

The short answer is no.

Upvotes: 0

Related Questions