Summary#
A single character. Write one in single quotes — 'A', '\n', '7' — the way C# does, and reach for it whenever
you are looking at text one character at a time: scanning a code, validating a format, splitting on a delimiter.
Signature#
char Initial = 'A';
char Delimiter = ',';
char Tab = '\t';Description#
A char is one character, not a one-character string, and the distinction earns its keep in two places.
It is what indexing and iteration give you. s[0] is the first character of s; foreach (var c in name) walks
them in order. Both read as a char, so the classification family below applies directly without a conversion step.
It picks the overload. s.Split(',') splits on one character; s.Split(", ") splits on a two-character
sequence. Those are different operations, they are different overloads in C#, and they stay different here.
Where it is stored#
On an entity, a char member is a one-character column. The width is the point: a column that could hold two
characters would let a row exist that the type says cannot.
Ordering#
Characters compare by code point, so a range test reads the way you would write it in C#:
c >= 'a' && c <= 'z'Classification#
char.IsDigit, char.IsLetter, char.IsLetterOrDigit, char.IsWhiteSpace, char.IsUpper, char.IsLower and
char.IsPunctuation each ask about a single character. char.ToUpper and char.ToLower hand back a char;
char.Parse turns a one-character string into one, and refuses a string of any other length rather than taking
its first character — s[0] is how you say that.
Each of these answers by Unicode category, not by an ASCII range. char.IsDigit('٠') is true — that is an
Arabic-Indic zero — and char.IsDigit('²') is false, because a superscript two is a number but not a digit. The
answer is the same in the browser and on the server.
One character means one UTF-16 unit#
A char holds a single UTF-16 code unit, exactly as in C#. Characters outside the Basic Multilingual Plane — most
emoji, some historic scripts — are two units, so they cannot be held in a char, and indexing into a string
containing one will land on half of it. When you are handling arbitrary user text rather than a code or a delimiter,
work with the string and its own operations instead.
Examples#
int CountDigits(string s) {
int n = 0;
foreach (var c in s) {
if (char.IsDigit(c)) { n = n + 1; }
}
return n;
}char Initial(string name) {
return name[0];
}entity Grade {
[Required, MaxLength(80)] string Subject;
char Letter;
security { allow read, create when IsAuthenticated; }
}string FirstField(string row) {
return row.Split(',')[0];
}The characters as an array — ToCharArray#
foreach (var ch in text) is the usual way to walk a string, and it is what most code wants. (It is the Text
module underneath, as every string verb is — you write the fluent form.) When you need the
characters as a value you can index, count or pass on, text.ToCharArray() hands them back as a char[] — C#'s own
spelling, doing C#'s own thing:
char[] letters = code.ToCharArray();
int n = letters.Length;See also#
- string literals — ordinary, verbatim and raw — the other quoting form, and the escapes both share
- Text.Length, Text.IsEmpty, Text.IsBlank, Text.Contains, Text.StartsWith, Text.EndsWith — asking a string a question: contains, starts with, index of