question

TZacks-2728 avatar image
0 Votes"
TZacks-2728 asked karenpayneoregon answered

c# Expression body advantage

I am using c# old version but like to know any advantages is there for Expression body or is it just a syntactic sugar ?

when my function has multiple lines then can we use expression body there to reduce the number of lines of code ?

how can i convert multiple lines of code with Expression body. if possible please discuss with a sample code. thanks

dotnet-csharp
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered

Hello,

There are times too use expression body members and other times not a good idea to use them. Then there is preference of the developer along with experience and readability.

Bottom line, it's your choice plus ask the question, do I need a statement body to properly debug code? Hope this helps.

Let's look at various ways to work with a switch.

BreakOutWithoutExpression is a conventional switch and easy to a) look and understand along with easy to set breakpoints used in ConventionalSwitch method. Now look at SimpleExpression using BreakOutWithExpression, if there is no need to debug and the values don't change this can be a candidate to use.

 namespace ConsoleApp1.Classes
 {
     public class Switches
     {
         private static bool BreakOutWithExpression(int index) => index switch { 11 => true, 15 => true, 19 => true, _ => false };
    
         public static void SimpleExpression()
         {
             for (int index = 0; index < 22; index++)
             {
                 if (!BreakOutWithExpression(index)) continue;
                 Console.WriteLine(index);
                 break;
             }
         }
    
         public static void ConventionalSwitch()
         {
             for (int index = 0; index < 22; index++)
             {
                 if (!BreakOutWithoutExpression(index)) continue;
                 Console.WriteLine(index);
                 break;
             }
         }
    
         private static bool BreakOutWithoutExpression(in int index)
         {
             var result = false;
                
             switch (index)
             {
                 case 11:
                 case 15:
                 case 19:
                     result = true;
                     break;
             }
    
             return result;
         }
     }
 }

Now let's look at using expressions for class properties. Here is makes sense to use expression body members for the get when using INotifyPropertyChanged Interface if there is nothing but getting a value.

 public class CustomerEntity : INotifyPropertyChanged
 {
     private int _customerIdentifier;
     private string _companyName;
     private int? _contactIdentifier;
     private string _firstName;
     private string _lastName;
     private int _contactTypeIdentifier;
     private string _contactTitle;
     private string _address;
     private string _city;
     private string _postalCode;
     private int? _countryIdentifier;
     private string _countyName;
     private Contacts _contacts;
    
     public int CustomerIdentifier
     {
         get => _customerIdentifier;
         set
         {
             _customerIdentifier = value;
             OnPropertyChanged();
         }
     }
     [Required]
     public string CompanyName
     {
         get => _companyName;
         set
         {
             _companyName = value;
             OnPropertyChanged();
         }
     }
    
     public int? ContactIdentifier
     {
         get => _contactIdentifier;
         set
         {
             _contactIdentifier = value;
             OnPropertyChanged();
         }
     }
    
     public Contacts Contacts
     {
         get => _contacts;
         set
         {
             _contacts = value;
             OnPropertyChanged();
         }
     }
    
     public string FirstName
     {
         get => _firstName;
         set
         {
             _firstName = value;
             OnPropertyChanged();
         }
     }
    
     public string LastName
     {
         get => _lastName;
         set
         {
             _lastName = value;
             OnPropertyChanged();
         }
     }
    
     public string ContactName => $"{FirstName} {LastName}";
     public string ContactFullName { get; set; } 
        
     public int? ContactTypeIdentifier
     {
         get => _contactTypeIdentifier;
         set
         {
             _contactTypeIdentifier = (int) value;
             OnPropertyChanged();
         }
     }
    
     public string ContactTitle
     {
         get => _contactTitle;
         set
         {
             _contactTitle = value;
             OnPropertyChanged();
         }
     }
    
     public string Street
     {
         get => _address;
         set
         {
             _address = value;
             OnPropertyChanged();
         }
     }
    
     public string City
     {
         get => _city;
         set
         {
             _city = value;
             OnPropertyChanged();
         }
     }
    
     public string PostalCode
     {
         get => _postalCode;
         set
         {
             _postalCode = value;
             OnPropertyChanged();
         }
     }
    
     public int? CountryIdentifier
     {
         get => _countryIdentifier;
         set
         {
             _countryIdentifier = value;
             OnPropertyChanged();
         }
     }
    
     public string CountryName
     {
         get => _countyName;
         set
         {
             _countyName = value;
             OnPropertyChanged();
         }
     }
    
     public event PropertyChangedEventHandler PropertyChanged;
     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
        
 }


Another example (this comes from a base class in a unit test project) for teaching about Indexes, makes sense that nothing is changing and if it did we could be calling a method that gets data from a data source

 public static string[] SomeOregonCities =>
     new[]
     {
         //              index from start    index from end                
         "Adams",        // 0                ^9
         "Albany",       // 1                ^8
         "Aloha",        // 2                ^7
         "Arlington",    // 3                ^6
         "Ashland",      // 4                ^5
         "Astoria",      // 5                ^4
         "Burns",        // 6                ^3
         "Jacksonville", // 7                ^2
         "Salem",        // 8                ^1
         "Portland"      // 9                ^0 (or array length)
     };

Usage

 public static void Range()
 {
    
     /*
      * Get last two cities with hard coded indices were ^ means start from
      * the bottom of the array.
      */
     foreach (var cityName in SomeOregonCities[^2..^0])
     {
         Debug.WriteLine(cityName);
     }
    
     Debug.WriteLine("");
    
    
     /*
      * Starting to get dynamic with indices
      */
     Index startIndex = 3;
     Index endIndex = ^4;
    
     Debug.WriteLine("Indices");
     Debug.WriteLine($"Start: {startIndex} End:{endIndex}");
    
     Debug.WriteLine($"{SomeOregonCities[startIndex]}, {SomeOregonCities[endIndex]}");
     Debug.WriteLine("");
    
    
     /*
      * We are fully dynamic for start index by first obtaining the city name using GetCityIndex
      * in the class StatementBase which this class implements             
      *
      */
     Debug.WriteLine("Indexing via first locating a city in the array");
    
     startIndex = new Index(GetCityIndex("Arlington"));
     Debug.WriteLine($"Start: {startIndex} End:{endIndex}");
    
     Debug.WriteLine($"{SomeOregonCities[startIndex]}, {SomeOregonCities[endIndex]}");
    
 }


Here is a no brainer (at least for me), less code to write for overrides of, in this case .ToString (works the same with or with expressions)


 namespace DmvLicensesConsoleApp.Models
 {
     public partial class DmvLicense
     {
         public string DriversLicenseNumber { get; set; }
         public DateTime? BirthDate { get; set; }
         public string SsnLastFour { get; set; }
         public string LastName { get; set; }
         public string FirstName { get; set; }
         public string MiddleName { get; set; }
         public string NameSuffix { get; set; }
         public string AddressLine1 { get; set; }
         public string AddressCity { get; set; }
         public string AddressZipCode { get; set; }
         public string MailingAddressLine1 { get; set; }
         public string MailingAddressCity { get; set; }
         public string MailingAddressZipCode { get; set; }
         public DateTime? ProcessDate { get; set; }
         public string DeceasedFlag { get; set; }
         public string WorkInLieuFlag { get; set; }
         public string ExpiredFlag { get; set; }
    
         public override string ToString() => $"{DriversLicenseNumber}, {ProcessDate:d}";
    
     }
 }


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.