The Nullity Operators
The Nullity Operators
Nullity Fundamental Operators
Introduction
We already know that, before using a variable you have declared or are declaring, you must initialize that variable. Here is an example:
using static System.Console;
int number = 100;
WriteLine("Number: {0}", number);
In this case, you know for sure that your variable has a value, because you made sure to assign a value to the variable before using it.
Practical Learning: Introducing Nullity
namespace Chemistry7.Models { public enum Phase { Gas, Liquid, Solid, Unknown } internal class Element(int number, string symbol, string name, double mass, Phase phase) { internal string ElementName { get { return name; } } internal string Symbol { get { return symbol; } } internal int AtomicNumber { get { return number; } } internal double AtomicWeight { get { return mass; } } internal Phase Phase { get { return phase; } } } }
using Chemistry6.Models; using static System.Console; void Present(Element obj) { if (obj != null) { WriteLine("Chemistry"); WriteLine("--------------------------"); WriteLine("Symbol: " + obj.Symbol); WriteLine($"Atomic Number: {obj.AtomicNumber}"); WriteLine("Element Name: " + obj.ElementName); WriteLine($"Atomic Weight: " + obj.AtomicWeight); WriteLine("Phase/State: " + obj.Phase); WriteLine("=========================="); } } Element Prepare() { Element h = new Element(1, "H", "Hydrogen", 1.008, Phase.Gas); Element he = new Element(2, "He", "Helium", 4.002602, Phase.Gas); Element li = new Element(3, "Li", "Lithium", 6.94, Phase.Solid); Element be = new Element(4, "Be", "Beryllium", 9.0121831, Phase.Solid); Element b = new Element(5, "B", "Boron", 10.81, Phase.Solid); Element c = new(name: "Carbon", mass: 12.011, symbol: "C", number: 6, phase: Phase.Solid); Element n = new(7, "N", "Nitrogen", 14.007, Phase.Gas); Element o = new(8, "O", "Oxygen", 15.999, Phase.Gas); Element f = new(9, "F", "Fluorine", 18.998, Phase.Gas); Element ne = new(10, "Ne", "Neon", 20.180, Phase.Gas); Element na = new(11, "Na", "Sodium", 22.990, Phase.Solid); Element mg = new(12, "Mg", "Magnesium", 24.305, Phase.Solid); Element al = new(phase : Phase.Solid, symbol : "Al", number : 13, name : "Aluminium", mass : 26.982); Element si = new(14, "Si", "Silicon", 28.085, Phase.Solid); Element p = new(symbol : "P", mass : 30.974, number : 15, name : "Phosphorus", phase : Phase.Solid); Element s = new(16, "S", "Sulfur", 32.06, Phase.Solid); Element cl = new(17, "Cl", "Chlorine", 35.45, Phase.Gas); Element ar = new Element(18, "Ar", "Argon", 39.948, Phase.Gas); Element k = new Element(phase: Phase.Solid, number: 19, symbol: "K", name: "Potassium", mass: 39.098); Element ca = new(20, "Ca", "Calcium", 40.078, Phase.Solid); Element sc = new(number: 21, symbol: "Sc", phase: Phase.Solid, name: "Scandium", mass: 44.956); Element ti = new(name: "Titanium", number: 22, symbol: "Ti", mass: 47.867, phase: Phase.Solid); Element v = new Element(number : 23, symbol : "V", phase : Phase.Solid, mass : 50.942, name : "Vanadium"); Element cr = new(number: 24, symbol: "Cr", phase: Phase.Solid, name: "Chromium", mass: 51.996); Element mn = new Element(name: "Manganese", number: 25, symbol: "Mn", mass: 54.938, phase: Phase.Solid); Element fe = new Element(mass: 55.845, symbol: "Fe", name: "Iron", number: 26, phase: Phase.Solid); Element co = new Element(symbol: "Co", number: 27, name: "Cobalt", mass: 58.933, phase: Phase.Solid); Element ni = new Element(number: 28, symbol: "Ni", mass: 58.6934, phase: Phase.Solid, name: "Nickel"); Element cu = new Element(phase: Phase.Solid, number: 29, name: "Copper", symbol: "Cu", mass: 63.546); Element zn = new Element(30, "Zn", "Zinc", 65.38, Phase.Solid); return zn; } Element? elm = null; WriteLine("Presenting a chemical element..."); Present(elm); elm = Prepare(); WriteLine("Presenting a chemical element..."); Present(elm);
Presenting a chemical element... Presenting a chemical element... Chemistry -------------------------- Symbol: Zn Atomic Number: 30 Element Name: Zinc Atomic Weight: 65.38 Phase/State: Solid ========================== Press any key to close this window . . .
The Null-Forgiving Operator
In some cases, the value of a variable may come by other means, such as from user (who may receive a request or prompt to type a value) or from a stream (computer memory, network, internet, etc). When that's the case, the compiler may issue a warning just to ask you whether you know for sure that the value of the variable or object will be provided. In most cases, this is a soft warning that will not produce an error but should be taken care of. In many cases, you can ignore that warning. The rule of thumb is that you should not ignore warnings, or at least you should always know the reason for a warning and probably take care of it.
The null-forgiving operator allows you to indicate to the compiler that you are aware that the variable or object may be holding a null value and you know what you are doing. The null-forgiving operator is !. To apply it, simply type it on the right side of the object or value. Here is an example:
using static System.Console;
int number = 100!;
WriteLine("Number: {0}", number);
Normally, the null-forgiving operator has no effect on a variable of primitive type when the variable is initialized immediately after you have declared it. If the value is supposed to be provided to the object or variable other than when initializing the object or variable, then the compiler would issue a warning. That's when you should apply the null-forgiving operator.
Practical Learning: Comparing an Object for Non-Nullity
using static System.Console; using Chemistry7.Models; void Present(Element obj) { if (obj != null) { WriteLine("Chemistry"); WriteLine("--------------------------"); WriteLine("Symbol: " + obj.Symbol); WriteLine($"Atomic Number: {obj.AtomicNumber}"); WriteLine("Element Name: " + obj.ElementName); WriteLine($"Atomic Weight: " + obj.AtomicWeight); WriteLine("Phase/State: " + obj.Phase); WriteLine("=========================="); } } Element Prepare() { Element h = new Element(1, "H", "Hydrogen", 1.008, Phase.Gas); Element he = new Element(2, "He", "Helium", 4.002602, Phase.Gas); Element li = new Element(3, "Li", "Lithium", 6.94, Phase.Solid); Element be = new Element(4, "Be", "Beryllium", 9.0121831, Phase.Solid); Element b = new Element(5, "B", "Boron", 10.81, Phase.Solid); Element c = new(name: "Carbon", mass: 12.011, symbol: "C", number: 6, phase: Phase.Solid); Element n = new(7, "N", "Nitrogen", 14.007, Phase.Gas); Element o = new(8, "O", "Oxygen", 15.999, Phase.Gas); Element f = new(9, "F", "Fluorine", 18.998, Phase.Gas); Element ne = new(10, "Ne", "Neon", 20.180, Phase.Gas); Element na = new(11, "Na", "Sodium", 22.990, Phase.Solid); Element mg = new(12, "Mg", "Magnesium", 24.305, Phase.Solid); Element al = new(phase : Phase.Solid, symbol : "Al", number : 13, name : "Aluminium", mass : 26.982); Element si = new(14, "Si", "Silicon", 28.085, Phase.Solid); Element p = new(symbol : "P", mass : 30.974, number : 15, name : "Phosphorus", phase : Phase.Solid); Element s = new(16, "S", "Sulfur", 32.06, Phase.Solid); Element cl = new(17, "Cl", "Chlorine", 35.45, Phase.Gas); Element ar = new Element(18, "Ar", "Argon", 39.948, Phase.Gas); Element k = new Element(phase: Phase.Solid, number: 19, symbol: "K", name: "Potassium", mass: 39.098); Element ca = new(20, "Ca", "Calcium", 40.078, Phase.Solid); Element sc = new(number: 21, symbol: "Sc", phase: Phase.Solid, name: "Scandium", mass: 44.956); Element ti = new(name: "Titanium", number: 22, symbol: "Ti", mass: 47.867, phase: Phase.Solid); Element v = new Element(number : 23, symbol : "V", phase : Phase.Solid, mass : 50.942, name : "Vanadium"); Element cr = new(number: 24, symbol: "Cr", phase: Phase.Solid, name: "Chromium", mass: 51.996); Element mn = new Element(name: "Manganese", number: 25, symbol: "Mn", mass: 54.938, phase: Phase.Solid); Element fe = new Element(mass: 55.845, symbol: "Fe", name: "Iron", number: 26, phase: Phase.Solid); Element co = new Element(symbol: "Co", number: 27, name: "Cobalt", mass: 58.933, phase: Phase.Solid); Element ni = new Element(number: 28, symbol: "Ni", mass: 58.6934, phase: Phase.Solid, name: "Nickel"); Element cu = new Element(phase: Phase.Solid, number: 29, name: "Copper", symbol: "Cu", mass: 63.546); Element zn = new Element(30, "Zn", "Zinc", 65.38, Phase.Solid); Element ga = new Element(31, "Ga", "Gallium", 69.723, Phase.Solid); return ga; } Element? elm = null; WriteLine("Presenting a chemical element..."); Present(elm!); elm = Prepare(); WriteLine("Presenting a chemical element..."); Present(elm);
Presenting a chemical element... Presenting a chemical element... Chemistry -------------------------- Symbol: Ga Atomic Number: 31 Element Name: Gallium Atomic Weight: 69.723 Phase/State: Solid ========================== Press any key to close this window . . .
using static System.Console; WriteLine("Stellar Water Point"); WriteLine("======================================================"); WriteLine("To prepare an invoice, enter the following information"); WriteLine("Types of Accounts"); WriteLine("1. Residential Household"); WriteLine("2. Laudromat"); WriteLine("3. Health Clinic"); WriteLine("4. Place of Worship/Youth Center"); WriteLine("5. Government Agency"); WriteLine("6. Other Business"); Write("Enter Type of Account: "); string answer = ReadLine(); WriteLine("------------------------------------------------------"); Write("Counter Reading Start: "); double counterReadingStart = double.Parse(ReadLine()!); Write("Counter Reading End: "); double counterReadingEnd = double.Parse(ReadLine()!); double first25Therms, next15Therms, above40Therms; double gallons = counterReadingEnd - counterReadingStart; double HCFTotal = gallons / 748; if (HCFTotal is > 40.00) { first25Therms = 25.00 * 1.5573; next15Therms = 15.00 * 1.2264; above40Therms = (HCFTotal - 40.00) * 0.9624; } else if (HCFTotal is > 25.00) { first25Therms = 25.00 * 1.5573; next15Therms = (HCFTotal - 25.00) * 1.2264; above40Therms = 0.00; } else // if (HCFTotal <= 25.00) { first25Therms = HCFTotal * 1.5573; next15Therms = 0.00; above40Therms = 0.00; } double waterUsageCharges = first25Therms + next15Therms + above40Therms; double sewerCharges = waterUsageCharges * 0.252; double environmentCharges = (answer == "1") ? (waterUsageCharges * 0.0025) : (waterUsageCharges * 0.0125); double serviceCharges = (answer == "1") ? (waterUsageCharges * 0.0328) : (waterUsageCharges * 0.11643); double totalCharges = waterUsageCharges + sewerCharges + environmentCharges + serviceCharges; double localTaxes = (answer == "1") ? (totalCharges * 0.035) : (totalCharges * 0.235); double stateTaxes = (answer == "1") ? (totalCharges * 0.115) : (totalCharges * 0.815); double amountDue = totalCharges + localTaxes + stateTaxes; WriteLine("======================================================"); WriteLine("Stellar Water Point - Customer Invoice"); WriteLine("======================================================"); WriteLine("Meter Reading"); WriteLine("------------------------------------------------------"); WriteLine("Counter Reading Start: {0,10}", counterReadingStart); WriteLine("Counter Reading End: {0,10}", counterReadingEnd); WriteLine("Total Gallons Consumed: {0,10}", gallons); WriteLine("======================================================"); WriteLine("Therms Evaluation"); WriteLine("------------------------------------------------------"); WriteLine("HCF Total: {0,10:n}", HCFTotal); WriteLine("First 35 Therms (* 1.5573): {0,10:n}", first25Therms); WriteLine("First 20 Therms (* 1.2264): {0,10:n}", next15Therms); WriteLine("Above 40 Therms (* 0.9624): {0,10:n}", above40Therms); WriteLine("------------------------------------------------------"); WriteLine("Water Usage Charges: {0,10:n}", waterUsageCharges); WriteLine("Sewer Charges: {0,10:n}", sewerCharges); WriteLine("======================================================"); WriteLine("Bill Values"); WriteLine("------------------------------------------------------"); WriteLine("Environment Charges: {0,10:n}", environmentCharges); WriteLine("Service Charges: {0,10:n}", serviceCharges); WriteLine("Total Charges: {0,10:n}", totalCharges); WriteLine("Local Taxes: {0,10:n}", localTaxes); WriteLine("State Taxes: {0,10:n}", stateTaxes); WriteLine("------------------------------------------------------"); WriteLine("Amount Due: {0,10:n}", amountDue); Write("======================================================");
Stellar Water Point ====================================================== To prepare an invoice, enter the following information Types of Accounts 1. Residential Household 2. Laudromat 3. Health Clinic 4. Place of Worship/Youth Center 5. Government Agency 6. Other Business Enter Type of Account: 2 ------------------------------------------------------ Counter Reading Start: 2205 Counter Reading End: 72877 ====================================================== Stellar Water Point - Customer Invoice ====================================================== Meter Reading ------------------------------------------------------ Counter Reading Start: 2205 Counter Reading End: 72877 Total Gallons Consumed: 70672 ====================================================== Therms Evaluation ------------------------------------------------------ HCF Total: 94.48 First 35 Therms (* 1.5573): 38.93 First 20 Therms (* 1.2264): 18.40 Above 40 Therms (* 0.9624): 52.43 ------------------------------------------------------ Water Usage Charges: 109.76 Sewer Charges: 27.66 ====================================================== Bill Values ------------------------------------------------------ Environment Charges: 1.37 Service Charges: 12.78 Total Charges: 151.57 Local Taxes: 35.62 State Taxes: 123.53 ------------------------------------------------------ Amount Due: 310.72 ====================================================== Press any key to close this window . . .
The Null-Conditional Operator
Consider a class used to describe some houses:
public class House { public int Bedrooms; public House() { Bedrooms = 1; } }
We already saw how to find out whether an object of such a class is currently valid. Here is an example:
int beds = -1;
House habitat = null;
Description desc = new Description();
if (habitat == null)
{
beds = 0;
}
else
{
beds = habitat.Bedrooms;
}
This would produce:
Make and Model: Farberware FMO12AHTBSG Capacity: 1.2 Microwave Options: 9 ========================================== Press any key to close this window . . .
In this case, we are trying to access a member of the class (getting the value of a property) only if the object is null. To simplify this operation, you can use the null-conditional operator represented as ?. (the question mark immediately followed by a period). To apply it, use it to access the member of a class. Here is an example:
int ? beds = 0; House habitat = null; Description desc = new Description(); beds = habitat?.Bedrooms;
Here is another version of the code:
int ?beds = -1;
Description desc = new Description();
House habitat = new House();
habitat.Bedrooms = 5;
beds = habitat?.Bedrooms;
The ?. operator checks whether the variable on its left is currently holding a null value. If it is, nothing happens. If it doesn't, then the member on its right is accessed and the operation that must be performed proceeds.
The Null Coalescing Operator
The ?. operator is used to simply check the nullity of a variable. You must apply the subsequent statement separately. To combine the ?. operation and its subsequent statement, you use the null coalescent operator represented as ?? (Two question marks). To apply it, type it after the condition followed by the desired statement. Here is an example:
int ?beds = -1;
Description desc = new Description();
House habitat = null;
beds = habitat?.Bedrooms ?? 0;
This code states that if the habitat object is null, the beds variable should be assigned 0. If the habitat object is not null, then the beds variable should receive a value from the designated property of the House class:
int ?beds = -1; Description desc = new Description(); House habitat = new House(); habitat.Bedrooms = 5; beds = habitat?.Bedrooms ?? 0;
Value and Object Casting
Introduction
An application typically deals with various values. Value compatibility is the ability of a certain value or a value of one type to be used as a value of another type. In many cases, this is not possible. In some other cases, you can convert one value into another. This conversion is referred to as casting. There are various ways you can cast a value, depending on its type.
Primitive Values and Memory Use
So far, we have use two data types for numeric variables. The types were int and double. A variable of type int can hold a value between -2,147,483,648 and 2,147,484,647. A variable of type double can hold a value between 1.79769313486232e308 and 1.79769313486232e308. This situation is based on memory usage. This means that the value held by an int variable can fit in the memory used by a double variable. As a result, you can assign an int variable to a double variable. Here is an example:
using static System.Console;
int natural = 938_482;
double real;
real = natural;
WriteLine("=========================");
WriteLine("Numbers");
WriteLine("-------------------------");
WriteLine("Natural: {0}", natural);
WriteLine("Decimal: {0}", real);
This would produce:
========================= Numbers ------------------------- Natural: 938482 Decimal: 938482 Press any key to close this window . . .
The amount of memory used to store the value of a double variable is larger than the amount of memory used to store the value of an int variable. As a result, you cannot assign a double variable to an int variable. If you do, you would receive an error. Consider the following an example:
using static System.Console; int natural = 938_482; double dec = 824.66; double real; real = natural; WriteLine("========================="); WriteLine("Numbers"); WriteLine("-------------------------"); WriteLine("Natural: {0}", natural); WriteLine("Decimal: {0}", real); WriteLine("Decimal: {0}", dec); natural = dec; WriteLine("Number: {0}", natural); WriteLine("=========================");
This would produce:
Severity Code Description Project File Line Suppression State Error CS0266 Cannot implicitly convert type 'double' to 'int'...
Casting a Value
Converting one value into another is referred to as casting. To make this possible, the value held by one variable must be able to fit in the memory area used by another variable. As we saw in the section before the previous, you can use the assignment operator. As an alternative, you precede the value with parentheses. In the parentheses, enter the data type of the holding variable. This can be done as follows:
using static System.Console;
int natural = 938_482;
double real;
real = (double)natural;
WriteLine("=========================");
WriteLine("Numbers");
WriteLine("-------------------------");
WriteLine("Natural: {0}", natural);
WriteLine("Decimal: {0}", real);
In the section before the last, we saw that, by defualt, the memory of a double variable is too large for the memory of an int variable and, by default, if you assign a double variable to an int variable, the compiler would produce an error. Sometimes, as a programmer of your own application, or an application with which you are familiar, you know with certainty that the value held by a double variable can fit in the memory of an int variable, but the compiler doesn't know. Therefore, to let the compiler know that you know that the value of one variable can fit in the memory of another certain variable, precede the value with parentheses and, in the parentheses, enter the data type of the holding variable. Consider a previous program that produced an error:
using static System.Console;
int natural = 938_482;
double dec = 824.66;
double real;
real = (int)natural;
WriteLine("=========================");
WriteLine("Numbers");
WriteLine("-------------------------");
WriteLine("Natural: {0}", natural);
WriteLine("Decimal: {0}", real);
WriteLine("Decimal: {0}", dec);
natural = (int)dec;
WriteLine("Number: {0}", natural);
WriteLine("=========================");
This would produce:
========================= Numbers ------------------------- Natural: 938482 Decimal: 938482 Decimal: 824.66 Number: 824 ========================= Press any key to close this window . . .
Conversion of an Object AS Another
One of the characteristics of object-oriented programming is that, when a child class is based on a parent class, the parent class tends to be compatible with its child(ren) class(es). This is because the parent class usually has the same number, types, and names of members as the child(ren) class(es). In many or most cases, the child(ren) class(es) has (have) more members than the parent class (or the parent class has fewer members than the child(ren) class(es).
Imagine that, at one time, you have a variable or object of a parent class but for some reason, you need to treat that object as if it were an object of the child class. The first operation you must perform is to let the compiler know that you want your variable to be mapped to the type of the parent class. To perform this operation, you use an operator named as. The basic formula to use it is:
start-expression as end-expression
The start-expression can be an object, in which case you can use that section to declare a variable. Initialize that variable with the object or value to be converted. The start-expression is followed by the as keyword. The end-expression is the type to which to convert. In most cases, it should be the same type used in the start-expression. After the conversion, you can use the object or the declared variable as if it were the type of the start-expression. Here is an example:
using static System.Console;
void Present(Appliance apl)
{
CofeeMaker? cm = apl as CofeeMaker;
WriteLine("Barrington World");
WriteLine("------------------------------------------");
WriteLine("Make and Model: " + cm?.Make + " " + cm?.Model);
WriteLine("Capacity: {0}", cm?.Capacity);
WriteLine("Serving Size: {0}", cm?.ServingSize);
WriteLine("Filter Type: {0}", cm?.FilterType);
WriteLine("==========================================");
}
CofeeMaker? machine;
machine = new CofeeMaker()
{
Make = "GE",
Capacity = "12 Cups",
Model = "JES1095SMSS",
ServingSize = "4-12 Cups (20-60oz)",
FilterType = "12-Cup Basket Style"
};
Present(machine);
public class Appliance
{
public required string Make { get; set; }
public required string Model { get; set; }
}
public class CofeeMaker : Appliance
{
public required string Capacity { get; set; }
public required string ServingSize { get; set; }
public required string FilterType { get; set; }
}
This would produce:
Barrington World ------------------------------------------ Make and Model: GE JES1095SMSS Capacity: 12 Cups Serving Size: 4-12 Cups (20-60oz) Filter Type: 12-Cup Basket Style ========================================== Press any key to close this window . . .
One of the most convenient ways to deal with objects compatibility is to use the object (or Object) class as your common type because it is the ultimate parent of all classes. You can then convert it to any object of your choice using the as operator. Here is an example:
using static System.Console;
void Present(object obj)
{
Microwave? mw = obj as Microwave;
WriteLine("Barrington World");
WriteLine("------------------------------------------");
WriteLine("Make and Model: " + mw?.Make + " " + mw?.Model);
WriteLine("Capacity: {0} Cubic Feet", mw?.Capacity);
if(mw?.MenuOptions == 0)
WriteLine("Microwave Options: N/A");
else
WriteLine("Microwave Options: {0}", mw?.MenuOptions);
WriteLine("Wattage: {0} Watts", mw?.Wattage);
WriteLine("==========================================");
}
Microwave? machine;
machine = new Microwave()
{
MenuOptions = 0,
Capacity = 0.9,
Wattage = 900,
Make = "GE",
Model = "JES1095SMSS"
};
Present(machine);
public class Microwave
{
public required string Make { get; set; }
public required string Model { get; set; }
public required double Capacity { get; set; }
public required int MenuOptions { get; set; }
public required int Wattage { get; set; }
}
This would produce:
Barrington World ------------------------------------------ Make and Model: GE JES1095SMSS Capacity: 0.9 Cubic Feet Microwave Options: N/A Wattage: 900 Watts ========================================== Press any key to close this window . . .
The Nullity of Members of a Class
The Nullity of a Field
We already know that when you are creating a class, if you judge it necessary, you can create one or more fields in the body of the class. This can be done as follows:
using static System.Console;
Letter let = new Letter();
let.Present();
WriteLine("======================");
public class Letter
{
int pos;
string name;
public Letter()
{
pos = 1;
name = "a";
}
public void Present()
{
WriteLine("Letter Characteristics");
WriteLine("----------------------");
WriteLine("Name: {0}", name);
WriteLine("Position: {0}", pos);
}
}
This would produce:
Letter Characteristics ---------------------- Name: a Position: 1 ====================== Press any key to close this window . . .
When you add a field to a class, the compiler would check the type of the field. If the type is nullable, the compiler may (or may not) present a warning. If you want to indicate to the compiler that you anticipate that the value of the field will be null or not in some cases, apply the ? operator to the nullable data type of the field. This can be done as follows:
using static System.Console;
Letter let = new Letter();
let.Present();
WriteLine("======================");
public class Letter
{
int pos;
string? name;
public Letter()
{
pos = 1;
name = "a";
}
public void Present()
{
WriteLine("Letter Characteristics");
WriteLine("----------------------");
WriteLine("Name: {0}", name);
WriteLine("Position: {0}", pos);
}
}
The Nullity of a Complete Property
Like a field of a class, a property can be a nullable type, such as a string. If you are creating a complete property, you know that the property and its corresponding field must be of the same type. Here is an example:
using static System.Console; Letter let = new Letter(); let.Position = 2; let.Name = "b"; let.Present(); WriteLine("======================"); public class Letter { int pos; string name; public int Position { get { return pos; } set { pos = value; } } public string Name { get { return name; } set { name = value; } } public void Present() { WriteLine("Letter Characteristics"); WriteLine("----------------------"); WriteLine("Name: {0}", Name); WriteLine("Position: {0}", Position); } }
This would produce:
Letter Characteristics ---------------------- Name: b Position: 2 ====================== Press any key to close this window . . .
When you create a property of a nullable type, the compiler wants you to know that the value(s) of the property could be null when the program eventually runs, and the compiler would issue a warning. To eliminate the warning, you have many solutions or options. One solution is to immediately initialize the property. If you are creating a complete property, you can initialize it corresponding field. This can be done as follows:
using static System.Console;
Letter let = new Letter();
let.Present();
WriteLine("======================");
public class Letter
{
int pos = 3;
string name = "c";
public int Position
{
get { return pos; }
set { pos = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public void Present()
{
WriteLine("Letter Characteristics");
WriteLine("----------------------");
WriteLine("Name: {0}", Name);
WriteLine("Position: {0}", Position);
}
}
This would produce:
Letter Characteristics ---------------------- Name: c Position: 3 ====================== Press any key to close this window . . .
In the above example, we initialized the field of the property with a constant value. Sometimes, or most of the time, you don't have, don't know, or can't predict the primary constant value. The solution is to apply the null-conditional operator. This can be done as follows:
public class Letter
{
int pos;
string? name;
public int Position
{
get { return pos; }
set { pos = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
}
Additionally, you can initialize the field of the property with the null. Either way, if you are creating a complete property, you should also apply the null conditional operator to the property. This can be done as follows:
using static System.Console;
Letter let = new();
let.Name = "d";
let.Position = 4;
let.Present();
WriteLine("======================");
public class Letter
{
int pos;
string? name = null;
public int Position
{
get { return pos; }
set { pos = value; }
}
public string? Name
{
get { return name; }
set { name = value; }
}
public void Present()
{
WriteLine("Letter Characteristics");
WriteLine("----------------------");
WriteLine("Name: {0}", Name);
WriteLine("Position: {0}", Position);
}
}
This would produce:
Letter Characteristics ---------------------- Name: d Position: 4 ====================== Press any key to close this window . . .
The Nullity of an Automatic Property
Normally, if you are creating a simple property, you can make it automatic. Here is an example:
public class House
{
public string PropertyNumber { get; set; }
public int Bedrooms { get; set; }
public float Bathrooms { get; set; }
public double MarketValue { get; set; }
}
If the type of property is nullable, you should indicate to the compiler that you are aware it. To do this, apply the null conditional operator to the type. This can be done as follows:
public class House
{
public string? PropertyNumber { get; set; }
public int Bedrooms { get; set; }
public float Bathrooms { get; set; }
public double MarketValue { get; set; }
}
Alternatively, you can initialize the property after its curly bracket. Here is an example:
public class House
{
public string PropertyNumber { get; set; } = null;
public int Bedrooms { get; set; }
public float Bathrooms { get; set; }
public double MarketValue { get; set; }
}
Practical Learning: Applying the Nullity to Propeties
namespace Chemistry7 { public enum Phase { Gas, Liquid, Solid, Unknown } internal class Element { internal string ? ElementName { get; set; } internal string ? Symbol { get; set; } internal int AtomicNumber { get; set; } internal double AtomicWeight { get; set; } internal Phase Phase { get; set; } public Element() { } public Element(string symbol) => Symbol = symbol; public Element(int number) => AtomicNumber = number; public Element(int number, string symbol, string name, double mass, Phase phase) { ElementName = name; AtomicWeight = mass; Phase = phase; Symbol = symbol; AtomicNumber = number; } } }
using static System.Console; WriteLine("Stellar Water Point"); WriteLine("======================================================"); WriteLine("To prepare an invoice, enter the following information"); WriteLine("Types of Accounts"); WriteLine("1. Residential Household"); WriteLine("2. Laudromat"); WriteLine("3. Health Clinic"); WriteLine("4. Place of Worship/Youth Center"); WriteLine("5. Government Agency"); WriteLine("6. Other Business"); Write("Enter Type of Account: "); string answer = ReadLine()!; WriteLine("------------------------------------------------------"); Write("Counter Reading Start: "); double counterReadingStart = double.Parse(ReadLine()!); Write("Counter Reading End: "); double counterReadingEnd = double.Parse(ReadLine()!); double first25Therms, next15Therms, above40Therms; double gallons = counterReadingEnd - counterReadingStart; double HCFTotal = gallons / 748; if (HCFTotal is > 40.00) { first25Therms = 25.00 * 1.5573; next15Therms = 15.00 * 1.2264; above40Therms = (HCFTotal - 40.00) * 0.9624; } else if (HCFTotal is > 25.00) { first25Therms = 25.00 * 1.5573; next15Therms = (HCFTotal - 25.00) * 1.2264; above40Therms = 0.00; } else // if (HCFTotal <= 25.00) { first25Therms = HCFTotal * 1.5573; next15Therms = 0.00; above40Therms = 0.00; } double waterUsageCharges = first25Therms + next15Therms + above40Therms; double sewerCharges = waterUsageCharges * 0.252; double environmentCharges = (answer == "1") ? (waterUsageCharges * 0.0025) : (waterUsageCharges * 0.0125); double serviceCharges = (answer == "1") ? (waterUsageCharges * 0.0328) : (waterUsageCharges * 0.11643); double totalCharges = waterUsageCharges + sewerCharges + environmentCharges + serviceCharges; double localTaxes = (answer == "1") ? (totalCharges * 0.035) : (totalCharges * 0.235); double stateTaxes = (answer == "1") ? (totalCharges * 0.115) : (totalCharges * 0.815); double amountDue = totalCharges + localTaxes + stateTaxes; WriteLine("======================================================"); WriteLine("Stellar Water Point - Customer Invoice"); WriteLine("======================================================"); WriteLine("Meter Reading"); WriteLine("------------------------------------------------------"); WriteLine("Counter Reading Start: {0,10}", counterReadingStart); WriteLine("Counter Reading End: {0,10}", counterReadingEnd); WriteLine("Total Gallons Consumed: {0,10}", gallons); WriteLine("======================================================"); WriteLine("Therms Evaluation"); WriteLine("------------------------------------------------------"); WriteLine("HCF Total: {0,10:n}", HCFTotal); WriteLine("First 35 Therms (* 1.5573): {0,10:n}", first25Therms); WriteLine("First 20 Therms (* 1.2264): {0,10:n}", next15Therms); WriteLine("Above 40 Therms (* 0.9624): {0,10:n}", above40Therms); WriteLine("------------------------------------------------------"); WriteLine("Water Usage Charges: {0,10:n}", waterUsageCharges); WriteLine("Sewer Charges: {0,10:n}", sewerCharges); WriteLine("======================================================"); WriteLine("Bill Values"); WriteLine("------------------------------------------------------"); WriteLine("Environment Charges: {0,10:n}", environmentCharges); WriteLine("Service Charges: {0,10:n}", serviceCharges); WriteLine("Total Charges: {0,10:n}", totalCharges); WriteLine("Local Taxes: {0,10:n}", localTaxes); WriteLine("State Taxes: {0,10:n}", stateTaxes); WriteLine("------------------------------------------------------"); WriteLine("Amount Due: {0,10:n}", amountDue); Write("======================================================");
Stellar Water Point ====================================================== To prepare an invoice, enter the following information Types of Accounts 1. Residential Household 2. Laudromat 3. Health Clinic 4. Place of Worship/Youth Center 5. Government Agency 6. Other Business Enter Type of Account: 2 ------------------------------------------------------ Counter Reading Start: 2205 Counter Reading End: 72877 ====================================================== Stellar Water Point - Customer Invoice ====================================================== Meter Reading ------------------------------------------------------ Counter Reading Start: 2205 Counter Reading End: 72877 Total Gallons Consumed: 70672 ====================================================== Therms Evaluation ------------------------------------------------------ HCF Total: 94.48 First 35 Therms (* 1.5573): 38.93 First 20 Therms (* 1.2264): 18.40 Above 40 Therms (* 0.9624): 52.43 ------------------------------------------------------ Water Usage Charges: 109.76 Sewer Charges: 27.66 ====================================================== Bill Values ------------------------------------------------------ Environment Charges: 1.37 Service Charges: 12.78 Total Charges: 151.57 Local Taxes: 35.62 State Taxes: 123.53 ------------------------------------------------------ Amount Due: 310.72 ====================================================== Press any key to close this window . . .
using static System.Console; using Chemistry7.Models; void Present(Element obj) { if (obj is not null) { WriteLine("Chemistry"); WriteLine("--------------------------"); WriteLine("Symbol: " + obj.Symbol); WriteLine($"Atomic Number: {obj.AtomicNumber}"); WriteLine("Element Name: " + obj.ElementName); WriteLine($"Atomic Weight: " + obj.AtomicWeight); WriteLine("Phase/State: " + obj.Phase); Write("=========================="); } } Element Prepare() { . . . Element mn = new(25, "Mn", "Manganese", 54.938, Phase.Solid); return mn; } Element elm = Prepare(); Present(elm);
Chemistry -------------------------- Symbol: Mn Atomic Number: 25 Element Name: Manganese Atomic Weight: 54.938 Phase/State: Solid ========================== Press any key to close this window . . .
namespace StellarWaterPoint2.Models { internal enum Classification { Residential, NonProfit, WaterIntensive, GeneralUse, Other } internal class WaterBill { private readonly string typeOfAccount; public WaterBill(string category) => typeOfAccount = category; public double CounterReadingStart { get; set; } public double CounterReadingEnd { get; set; } public (Classification @class, string name) AccountType { get { if (typeOfAccount == "1") return (Classification.Residential, "Residential Household"); else if (typeOfAccount == "2") return (Classification.NonProfit, "Social/Non-Profit Organization"); else if (typeOfAccount == "3") return (Classification.WaterIntensive, "Water Intensive Business (Laudromat, Hair Salon, etc)"); else if (typeOfAccount == "4") return (Classification.GeneralUse, "General Business, Government"); else return (Classification.Other, "Other"); } } public double Gallons => CounterReadingEnd - CounterReadingStart; public double HCFTotal => Gallons / 748; public (double First25Therms, double Next15Therms, double Above40Therms) Therms { get { double first, next, above; if (HCFTotal is > 40.00) { first = 25.00 * 1.5573; next = 15.00 * 1.2264; above = (HCFTotal - 40.00) * 0.9624; } else if (HCFTotal > 25.00) { first = 25.00 * 1.5573; next = (HCFTotal - 25.00) * 1.2264; above = 0.00; } else { first = HCFTotal * 1.5573; next = 0.00; above = 0.00; } return (first, next, above); } } public double WaterUsageCharges => Therms.First25Therms + Therms.Next15Therms + Therms.Above40Therms; public double SewerCharges { get { double result = AccountType.@class switch { Classification.Residential => WaterUsageCharges * 0.2528, Classification.NonProfit => WaterUsageCharges * 0.0915, Classification.WaterIntensive => WaterUsageCharges * 1.5865, Classification.GeneralUse => WaterUsageCharges * 0.6405, _ => WaterUsageCharges * 1.2125 }; return result; } } public double EnvironmentCharges { get { double result = AccountType.@class switch { Classification.Residential => WaterUsageCharges * 0.0025, Classification.NonProfit => WaterUsageCharges * 0.0015, Classification.WaterIntensive => WaterUsageCharges * 0.0105, Classification.GeneralUse => WaterUsageCharges * 0.0045, _ => WaterUsageCharges * 0.0125 }; return result; } } public double ServiceCharges { get => AccountType.@class switch { Classification.Residential => WaterUsageCharges * 0.0328, Classification.NonProfit => WaterUsageCharges * 0.0115, Classification.WaterIntensive => WaterUsageCharges * 0.1015, Classification.GeneralUse => WaterUsageCharges * 0.0808, _ => WaterUsageCharges * 0.1164 }; } public double TotalCharges => WaterUsageCharges + SewerCharges + EnvironmentCharges + ServiceCharges; public double LocalTaxes { get => AccountType.@class switch { Classification.Residential => TotalCharges * 0.115, Classification.NonProfit => TotalCharges * 0.085, Classification.WaterIntensive => TotalCharges * 0.825, Classification.GeneralUse => TotalCharges * 0.315, _ => TotalCharges * 0.625 }; } public double StateTaxes => AccountType.@class switch { Classification.Residential => TotalCharges * 0.035, Classification.NonProfit => TotalCharges * 0.015, Classification.WaterIntensive => TotalCharges * 0.105, Classification.GeneralUse => TotalCharges * 0.065, _ => TotalCharges * 0.815 }; public double AmountDue => TotalCharges + LocalTaxes + StateTaxes; } }
using StellarWaterPoint2.Models; using static System.Console; WriteLine("Stellar Water Point"); WriteLine("==========================================================="); WriteLine("To prepare an invoice, enter the following information"); WriteLine("Types of Accounts"); WriteLine("1. Residential Household"); WriteLine("2. Social/Non-Profit Organization"); WriteLine("3. Water Intensive Business (Laudromat, etc)"); WriteLine("4. General Business"); WriteLine("0. Other"); Write("Enter Type of Account: "); string answer = ReadLine()!; WriteLine("-----------------------------------------------------------"); WaterBill bill = new WaterBill(answer); Write("Counter Reading Start: "); bill.CounterReadingStart = int.Parse(ReadLine()!); Write("Counter Reading End: "); bill.CounterReadingEnd = int.Parse(ReadLine()!); WriteLine("==========================================================="); WriteLine("Stellar Water Point - Customer Invoice"); WriteLine("Account Type: {0}", bill.AccountType.name); WriteLine("==========================================================="); WriteLine("Meter Reading"); WriteLine("-----------------------------------------------------------"); WriteLine("Counter Reading Start: {0,10}", bill.CounterReadingStart); WriteLine("Counter Reading End: {0,10}", bill.CounterReadingEnd); WriteLine("Total Gallons Consumed: {0,10}", bill.Gallons); WriteLine("==========================================================="); WriteLine("Therms Evaluation"); WriteLine("-----------------------------------------------------------"); WriteLine("HCF Total: {0,10:n}", bill.HCFTotal); WriteLine("First 35 Therms (* 1.5573): {0,10:n}", bill.Therms.First25Therms); WriteLine("First 20 Therms (* 1.2264): {0,10:n}", bill.Therms.Next15Therms); WriteLine("Above 40 Therms (* 0.9624): {0,10:n}", bill.Therms.Above40Therms); WriteLine("-----------------------------------------------------------"); WriteLine("Water Usage Charges: {0,10:n}", bill.WaterUsageCharges); WriteLine("Sewer Charges: {0,10:n}", bill.SewerCharges); WriteLine("==========================================================="); WriteLine("Bill Values"); WriteLine("-----------------------------------------------------------"); WriteLine("Environment Charges: {0,10:n}", bill.EnvironmentCharges); WriteLine("Service Charges: {0,10:n}", bill.ServiceCharges); WriteLine("Total Charges: {0,10:n}", bill.TotalCharges); WriteLine("Local Taxes: {0,10:n}", bill.LocalTaxes); WriteLine("State Taxes: {0,10:n}", bill.StateTaxes); WriteLine("-----------------------------------------------------------"); WriteLine("Amount Due: {0,10:n}", bill.AmountDue); Write("===========================================================");
Stellar Water Point =========================================================== To prepare an invoice, enter the following information Types of Accounts 1. Residential Household 2. Social/Non-Profit Organization 3. Water Intensive Business (Laudromat, etc) 4. General Business 0. Other Enter Type of Account: 1 ----------------------------------------------------------- Counter Reading Start: 26526 Counter Reading End: 42528 =========================================================== Stellar Water Point - Customer Invoice Account Type: Residential Household =========================================================== Meter Reading ----------------------------------------------------------- Counter Reading Start: 26526 Counter Reading End: 42528 Total Gallons Consumed: 16002 =========================================================== Therms Evaluation ----------------------------------------------------------- HCF Total: 21.39 First 35 Therms (* 1.5573): 33.32 First 20 Therms (* 1.2264): 0.00 Above 40 Therms (* 0.9624): 0.00 ----------------------------------------------------------- Water Usage Charges: 33.32 Sewer Charges: 8.42 =========================================================== Bill Values ----------------------------------------------------------- Environment Charges: 0.08 Service Charges: 1.09 Total Charges: 42.91 Local Taxes: 4.94 State Taxes: 1.50 ----------------------------------------------------------- Amount Due: 49.35 =========================================================== Press any key to close this window . . .
A Property of a Reference Type
You know that you can create a type that is the type of a class. You can create the property fully implemented. Here is an example:
public class Camera
{
public string? Location { get; set; }
}
public class TrafficTicket
{
public Camera Recorder { get; set; }
}
In this case, the compiler would issue a warning to let you know that the value(s) of the property could be null, which is a bad thing. To avoid the warning, you can apply the null conditional operator on the property. This can be done as follows:
public class Camera
{
public string? Location { get; set; }
}
public class TrafficTicket
{
public Camera? Recorder { get; set; }
}
Practical Learning: Ending the Lesson
|
|||
Previous | Copyright © 2001-2024, FunctionX | Sunday 30 April 2023, 13:18 | Next |
|