Accessing fields in LINQ query for customers with overdue balances
This is a pretty good attempt for someone just starting out. However, there is always a lot to learn and the books never seem to take advantage of all the latest language features.

The first thing I'm going to tell you to do is stop abbreviating everything. You don't pay extra for full naming.

I'll choose you constructor to highlight this:

public Customer(string name, string phn, string addr, decimal         bal)
{
    CustName = name;
    CustPhone = phn;
    CustAddress = addr;
    CustBalance = bal;
}


First, Customer is a great name, name is also good.

Now, string phn I'd guess at phoneNumber but it could also be the name of the Primary Health Network if this was an Australian healthcare customer. string addr - is address really that much harder to type? decimal is a great choice for the balance but bal is a terrible name and there's some extra whitespace which should be removed.

Also, your fields shouldn't start with Cust. They should aslo be camelCase. The old version of the guidelines stated this explicitly but the newer C# standards don't specify a convention for non public fields. Most people use camelCase in my experience. As a commenter has mentioned, you can use auto properties:

public string Name { get; set; }
public decimal Balance { get;set; }


You can set them directly in your constructor.



I'm assuming you're using the latest and greatest C# for the next few points. I can't remember when collection initializers were introduced but it's a while ago now.

This is a very common pattern:

List&lt;Customer&gt; customers = new List&lt;Customer&gt;();
customers.Add(new Customer("Alan", "80911291", "ABC Street", 25.60m));
customers.Add(new Customer("Bill", "19872131", "DEF Street", -32.10m));
customers.Add(new Customer("Carl", "29812371", "GHI Street", -12.2m));
customers.Add(new Customer("David", "78612312", "JKL Street", 12.6m));


It's so common, we have a construct to make it easier:

var customers = new List&lt;Customer&gt;
{
    new Customer("Alan", "80911291", "ABC Street", 25.60m),
    new Customer("Bill", "19872131", "DEF Street", -32.10m),
    new Customer("Carl", "29812371", "GHI Street", -12.2m),
    new Customer("David", "78612312", "JKL Street", 12.6m)
};


That's a lot less typing and a bit easier to scan IMO.

We also now have string interpolation (this one is much newer):

Console.WriteLine("Name = {0}, Balance = {1}", cust.Name, cust.Balance);


Can become:

Console.WriteLine($"Name = {cust.Name}, Balance = {cust.Balance}");


Which is a lot less scanning backwards and forwards to see what goes where.



For the sake of completeness, let's look at your naming here:

var overdue =
    from cust in customers
    where cust.Balance &lt; 0
    orderby cust.Balance ascending
    select new { cust.Name, cust.Balance };


overdue is better as overdueCustomers.
from customer in customers is equally better than using cust which isn't a word.

You could then finally do a foreach (var overdueCustomer in overdueCustomers) to make it obvious everywhere in the code that the reason you're interested in this particular customer is that they are overdue.

Edit

As noted in a comment from Peter Taylor, overdrawnCustomers is an even better name. It doesn't have the date connotation that overdue does.