Subsections of Programming Style Requirements
All programming will be done using Microsoft Visual Studio® Community 2022. This integrated development environment (IDE) does a certain amount of formatting automatically. All code formatting should be consistent with what the IDE does automatically, including how it formats code stubs that it inserts. Specifically, all braces should occur on lines by themselves, vertically aligned so that matching braces occupy the same column. (An exception to this rule can be made when the braces enclose a single statement or a part of a statement, and they occur on the same line; however, if it is possible to omit the braces, as in an if statement, this is preferable to placing them on the same line.) Furthermore, blocks of code enclosed by braces should be indented one tab stop inside the braces.
Tip
An easy way to format a file consistently (after removing any syntax errors) is to select from the “Edit” menu, “Advanced -> Format Document”.
Warning
Don’t change the formatting defaults in the IDE.
Access Modifiers
Access Modifiers
C# provides 4 access modifiers for classes, fields, etc.: public, internal, protected, and private. For simplicity, however, we will not allow the use of the internal or protected access modifiers unless they are required by the compiler (for example, when overriding a protected method).
When classes, fields, etc., are declared, C# does not require that an access modifier be used. If the access modifier is omitted, a default accessibility level will be used. However, the default depends on where it is being declared. For example, the default accessibility level of a top-level type is internal, whereas the default accessibility level of a class member is private. In order to avoid confusion, we will require that access modifiers (i.e., public or private) be used on all declarations except where C# does not allow them (C# does not allow access modifiers for namespaces, members of interfaces or enumerations, or local variables within methods). In particular, note that when Visual Studio® automatically generates a class statement, it does not always supply an access modifier, or it may use internal. We require that the statement be changed to use public (C# does not allow private here).
In addition, fields within classes and structures should be declared private, unless they are also declared either const or readonly. If you want to make a variable accessible to outside code, you can instead do something like the following:
public double Force { get; set; }
Or if you want the outside code to be able to access it, but you don’t
want it to change its value you can instead define it as:
public double Force { get; private set; }
In these examples, Force
is not a field, but a property. It can be used like a field, but defining it as a property makes it more maintainable (see “Properties” for more details).
Warning
Don’t define a private property when a private field will accomplish the same thing - using a private field with the appropriate naming convention makes the code more readable.
For more information on access modifiers and accessibility levels, see the section on Accessibility Levels in the C# Reference.
Naming Conventions
Naming Conventions
The naming conventions described below use the following terminology:
- Pascal case: Multiple words are joined without spaces, using
capital letters at the beginning of each word. If acronyms of 3 or
more letters are included, only the first letter of the acronym is
capitalized. For example,
AverageAge
, ContextBoundObject
, RgbCode
. - Camel case: The same as pascal case, except the first letter is
not capitalized. For example,
averageAge
, contextBoundObject
,
rgbCode
.
Namespaces
In CIS 300 programming assignments, namespace names will typically be provided. They will use the form Ksu.Cis300.ProgramName
, where each of the 3 components is in pascal case. For example:
namespace Ksu.Cis300.Spreadsheet
{
}
Classes, Structures, and Enumerations
Use pascal case. If the name begins with “I”, the following letter must not be capitalized, as this would look like an interface - see below. For an exception class, append the word “Exception”. Make your names descriptive nouns or noun phrases without abbreviations (common abbreviations like “Min” are allowed). For example:
public class AccountManager
{
}
Use the convention for a class name with a capital “I” preceding the first letter (which must also be capitalized). For example:
public interface IPriorityQueue
{
}
Methods
Use pascal case. Make your names descriptive without abbreviations (common abbreviations like “Min” are allowed). For example:
private void InitializeComponent()
{
}
Warning
Automatically-generated event handlers don’t follow this convention. For example, suppose you generate a Click event handler by double-clicking a Button named uxUpdate
. The event handler generated will then be given a name of uxUpdate_Click. You will need to rename it to UpdateClick. Be sure to use Visual Studio’s Rename feature, as this name will also need to be changed in automatically-generated code that you normally won’t edit.
Use pascal case. Make your names descriptive without abbreviations (common abbreviations are allowed). For example:
public int Count { get; private set; }
Use camel case, and begin names with “ux” followed by a capital letter
(this “ux” stands for “user experience”). Make your names descriptive
of the functionality, not the type of control. For example,
uxAccept
, uxCustomerName
.
Note
You will not typically declare these names in code, but will enter
them in the Visual Studio® design window.
public Constants (const or readonly)
Use pascal case. Make your names descriptive. For example:
public const double GravitationalAcceleration = 9.80665;
private Fields
Use camel case with an underscore character preceding the first letter. For example:
This applies to all private fields, including those defined as const or readonly.
Parameters and Local Variables Within Methods
Use camel case. For example, inString
and outString
in the
following code:
public string ToMixedCase(string inString)
{
string outString;
// code here
return outString;
}
Within each source code file that you edit, you will need to provide
certain comments as documentation. Visual Studio® automatically
generates some source code files that you will not need to modify — you don’t need to add comments to those files.
At the top of each file in which you provide code, add a comment of the following form:
/* filename.cs
* Author: Name
*/
where filename.cs
is the name of the file, and Name
is the name of
the primary author. The primary author will either be you or, for
files provided for you, the name of the original author of that
file. Whenever you use someone else’s code, it is important that you
give them credit for it. (To fail to do this is plagiarism.) Thus, if
one of your source files was originally written by Rod Howell, leave
his name as the author. If you have modified a file originally written
by someone else, below the Author
line, insert a line of the following form:
/*
* Modified by: Your Name
*/
Prior to each class, structure, enumeration, field, property, and method, place a comment documenting its use. This comment should be delimited by ///
on each line. When you type ///
immediately above a class, structure, enumeration, field, property, or method, the IDE will automatically insert additional text to form a comment stub such as:
/// <summary>
///
/// </summary>
<summary>
and </summary>
are XML tags, which are understood by
the IDE. Between these tags, you should insert a summary of the
program component you are documenting, including any requirements that
must be satisfied by the calling code in order for the method to work
properly. For example:
/// <summary>
/// Indicates whether this structure is empty.
/// </summary>
private bool _isEmpty;
If the program component being documented is a method with at least one parameter and/or a non-void return type, additional XML tags will be generated by the IDE. For each parameter, <param>
and </param>
tags will be generated. You should insert a description of the use of that parameter between these tags. If the method has a non-void return type, <returns>
and </returns>
tags are generated. You should insert an explanation of the value being returned between these tags. For example:
/// <summary>
/// Computes the number of times a given string x
/// occurs within a given string y.
/// </summary>
/// <param name="x">The string being searched for.</param>
/// <param name="y">The string being searched.</param>
/// <returns>The number of occurrences of x in y.</returns>
private int Occurrences(string x, string y)
{
}
Note
You do not need to fill in <exception>
tags - you may remove any that are generated automatically.
Visual Studio often generates warnings when it cannot verify that the value being assigned to a non-nullable variable is not null. In cases where you can determine that the value will not be null, you are allowed to remove the warning by inserting !
after the value. In such cases, prior to this line, insert a comment explaining why this value is not null. For example:
string line;
while (!input.EndOfStream)
{
// Because input isn't at the end of the stream, ReadLine won't return null.
line = input.ReadLine()!;
}
Comments should also be used within methods to explain anything that is not obvious from the code itself.
Prohibited Features
Prohibited Features
The following features of C# should not be used on assignments or quizzes unless otherwise stated:
The goto statement: It has been over 50 years since Dijkstra published “Go To Statement Considered Harmful” (Communications of the ACM, vol. 11 (1968), pp. 147-148). I am
amazed that languages continue to include this statement.
The unsafe keyword: The name pretty much says it all.
The var keyword: There are very few contexts in which this is needed, and these contexts won’t occur in this class. For all other contexts, it makes the code less readable.
Virtual methods: These are useful in large-scale software development; however, they are overused. They will not be needed in the programming we will be doing. (However, virtual methods in the .NET class library may be overridden.)
Abbreviated constructor calls: Beginning with C# version 9.0, constructor calls are allowed to be abbreviated when the compiler can determine from the context the type of object that is being constructed. In such a case, the type name can be omitted from the new operator. For example, instead of writing:
StringBuilder sb = new StringBuilder();
we can write:
StringBuilder sb = new();
If the constructor takes parameters, they can be inserted between the parentheses. Such abbreviations are permitted - even encouraged - in cases like the above example, where the type being constructed is explicitly specified elsewhere in the same statement. However, if the type name is not explicitly specified elsewhere in the same statement, such abbreviations are prohibited, as they make the code harder to read.