diff --git a/snippets/csharp/System/AppContext/Overview/V1/Example4.cs b/snippets/csharp/System/AppContext/Overview/V1/Example4.cs new file mode 100644 index 00000000000..7b86a80ab5e --- /dev/null +++ b/snippets/csharp/System/AppContext/Overview/V1/Example4.cs @@ -0,0 +1,37 @@ +// +using System; +using System.Reflection; + +[assembly: AssemblyVersion("1.0.0.0")] + +public static class StringLibrary1 +{ + public static int SubstringStartsAt(string fullString, string substr) + { + return fullString.IndexOf(substr, StringComparison.Ordinal); + } +} +// + +namespace App +{ + // + using System; + + public class Example1 + { + public static void Main() + { + string value = "The archaeologist"; + string substring = "archæ"; + int position = StringLibrary1.SubstringStartsAt(value, substring); + if (position >= 0) + Console.WriteLine($"'{substring}' found in '{value}' starting at position {position}"); + else + Console.WriteLine($"'{substring}' not found in '{value}'"); + } + } + // The example displays the following output: + // 'archæ' not found in 'The archaeologist' + // +} diff --git a/snippets/csharp/System/AppContext/Overview/V1/Project.csproj b/snippets/csharp/System/AppContext/Overview/V1/Project.csproj new file mode 100644 index 00000000000..369b05a893e --- /dev/null +++ b/snippets/csharp/System/AppContext/Overview/V1/Project.csproj @@ -0,0 +1,9 @@ + + + + Library + net10.0 + false + + + diff --git a/snippets/csharp/System/AppContext/Overview/V2/Example6.cs b/snippets/csharp/System/AppContext/Overview/V2/Example6.cs new file mode 100644 index 00000000000..c31bea12489 --- /dev/null +++ b/snippets/csharp/System/AppContext/Overview/V2/Example6.cs @@ -0,0 +1,37 @@ +// +using System; +using System.Reflection; + +[assembly: AssemblyVersion("2.0.0.0")] + +public static class StringLibrary2 +{ + public static int SubstringStartsAt(string fullString, string substr) + { + return fullString.IndexOf(substr, StringComparison.CurrentCulture); + } +} +// + +namespace App +{ + // + using System; + + public class Example2 + { + public static void Main() + { + string value = "The archaeologist"; + string substring = "archæ"; + int position = StringLibrary2.SubstringStartsAt(value, substring); + if (position >= 0) + Console.WriteLine($"'{substring}' found in '{value}' starting at position {position}"); + else + Console.WriteLine($"'{substring}' not found in '{value}'"); + } + } + // The example displays the following output: + // 'archæ' found in 'The archaeologist' starting at position 4 + // +} diff --git a/snippets/csharp/System/AppContext/Overview/V2/Project.csproj b/snippets/csharp/System/AppContext/Overview/V2/Project.csproj new file mode 100644 index 00000000000..369b05a893e --- /dev/null +++ b/snippets/csharp/System/AppContext/Overview/V2/Project.csproj @@ -0,0 +1,9 @@ + + + + Library + net10.0 + false + + + diff --git a/snippets/csharp/System/AppContext/Overview/V3/Example8.cs b/snippets/csharp/System/AppContext/Overview/V3/Example8.cs new file mode 100644 index 00000000000..585f7e8eaec --- /dev/null +++ b/snippets/csharp/System/AppContext/Overview/V3/Example8.cs @@ -0,0 +1,41 @@ +// +using System; +using System.Reflection; + +[assembly: AssemblyVersion("2.0.0.0")] + +public static class StringLibrary +{ + public static int SubstringStartsAt(string fullString, string substr) + { + bool flag; + if (AppContext.TryGetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison", out flag) && flag == true) + return fullString.IndexOf(substr, StringComparison.Ordinal); + else + return fullString.IndexOf(substr, StringComparison.CurrentCulture); + } +} +// + +namespace App +{ + // + using System; + + public class Example + { + public static void Main() + { + string value = "The archaeologist"; + string substring = "archæ"; + int position = StringLibrary.SubstringStartsAt(value, substring); + if (position >= 0) + Console.WriteLine($"'{substring}' found in '{value}' starting at position {position}"); + else + Console.WriteLine($"'{substring}' not found in '{value}'"); + } + } + // The example displays the following output: + // 'archæ' found in 'The archaeologist' starting at position 4 + // +} diff --git a/snippets/csharp/System/AppContext/Overview/V3/Project.csproj b/snippets/csharp/System/AppContext/Overview/V3/Project.csproj new file mode 100644 index 00000000000..369b05a893e --- /dev/null +++ b/snippets/csharp/System/AppContext/Overview/V3/Project.csproj @@ -0,0 +1,9 @@ + + + + Library + net10.0 + false + + + diff --git a/snippets/csharp/System/Boolean/Overview/Project.csproj b/snippets/csharp/System/Boolean/Overview/Project.csproj new file mode 100644 index 00000000000..22dd9034898 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/Project.csproj @@ -0,0 +1,9 @@ + + + + Library + net10.0 + true + + + diff --git a/snippets/csharp/System/Boolean/Overview/binary1.cs b/snippets/csharp/System/Boolean/Overview/binary1.cs new file mode 100644 index 00000000000..157211ddb53 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/binary1.cs @@ -0,0 +1,35 @@ +// +using System; + +public class Example1 +{ + public static void Main() + { + bool[] flags = { true, false }; + foreach (var flag in flags) + { + // Get binary representation of flag. + Byte value = BitConverter.GetBytes(flag)[0]; + Console.WriteLine($"Original value: {flag}"); + Console.WriteLine($"Binary value: {value} ({GetBinaryString(value)})"); + // Restore the flag from its binary representation. + bool newFlag = BitConverter.ToBoolean(new Byte[] { value }, 0); + Console.WriteLine($"Restored value: {newFlag}{Environment.NewLine}"); + } + } + + private static string GetBinaryString(Byte value) + { + string retVal = Convert.ToString(value, 2); + return new string('0', 8 - retVal.Length) + retVal; + } +} +// The example displays the following output: +// Original value: True +// Binary value: 1 (00000001) +// Restored value: True +// +// Original value: False +// Binary value: 0 (00000000) +// Restored value: False +// diff --git a/snippets/csharp/System/Boolean/Overview/conversion1.cs b/snippets/csharp/System/Boolean/Overview/conversion1.cs new file mode 100644 index 00000000000..a73bec266ee --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/conversion1.cs @@ -0,0 +1,32 @@ +// +using System; + +public class Example2 +{ + public static void Main() + { + Byte byteValue = 12; + Console.WriteLine(Convert.ToBoolean(byteValue)); + Byte byteValue2 = 0; + Console.WriteLine(Convert.ToBoolean(byteValue2)); + int intValue = -16345; + Console.WriteLine(Convert.ToBoolean(intValue)); + long longValue = 945; + Console.WriteLine(Convert.ToBoolean(longValue)); + SByte sbyteValue = -12; + Console.WriteLine(Convert.ToBoolean(sbyteValue)); + double dblValue = 0; + Console.WriteLine(Convert.ToBoolean(dblValue)); + float sngValue = .0001f; + Console.WriteLine(Convert.ToBoolean(sngValue)); + } +} +// The example displays the following output: +// True +// False +// True +// True +// True +// False +// True +// diff --git a/snippets/csharp/System/Boolean/Overview/conversion3.cs b/snippets/csharp/System/Boolean/Overview/conversion3.cs new file mode 100644 index 00000000000..5cc0408da7f --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/conversion3.cs @@ -0,0 +1,32 @@ +// +using System; + +public class Example3 +{ + public static void Main() + { + bool flag = true; + + byte byteValue; + byteValue = Convert.ToByte(flag); + Console.WriteLine($"{flag} -> {byteValue}"); + + sbyte sbyteValue; + sbyteValue = Convert.ToSByte(flag); + Console.WriteLine($"{flag} -> {sbyteValue}"); + + double dblValue; + dblValue = Convert.ToDouble(flag); + Console.WriteLine($"{flag} -> {dblValue}"); + + int intValue; + intValue = Convert.ToInt32(flag); + Console.WriteLine($"{flag} -> {intValue}"); + } +} +// The example displays the following output: +// True -> 1 +// True -> 1 +// True -> 1 +// True -> 1 +// diff --git a/snippets/csharp/System/Boolean/Overview/format3.cs b/snippets/csharp/System/Boolean/Overview/format3.cs new file mode 100644 index 00000000000..f9d31889233 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/format3.cs @@ -0,0 +1,64 @@ +// +using System; +using System.Globalization; + +public class Example4 +{ + public static void Main() + { + String[] cultureNames = { "", "en-US", "fr-FR", "ru-RU" }; + foreach (var cultureName in cultureNames) { + bool value = true; + CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName); + BooleanFormatter formatter = new BooleanFormatter(culture); + + string result = string.Format(formatter, "Value for '{0}': {1}", culture.Name, value); + Console.WriteLine(result); + } + } +} + +public class BooleanFormatter : ICustomFormatter, IFormatProvider +{ + private CultureInfo culture; + + public BooleanFormatter() : this(CultureInfo.CurrentCulture) + { } + + public BooleanFormatter(CultureInfo culture) + { + this.culture = culture; + } + + public Object GetFormat(Type formatType) + { + if (formatType == typeof(ICustomFormatter)) + return this; + else + return null; + } + + public string Format(string fmt, Object arg, IFormatProvider formatProvider) + { + // Exit if another format provider is used. + if (! formatProvider.Equals(this)) return null; + + // Exit if the type to be formatted is not a Boolean + if (! (arg is Boolean)) return null; + + bool value = (bool) arg; + return culture.Name switch + { + "en-US" => value.ToString(), + "fr-FR" => value ? "vrai" : "faux", + "ru-RU" => value ? "верно" : "неверно", + _ => value.ToString(), + }; + } +} +// The example displays the following output: +// Value for '': True +// Value for 'en-US': True +// Value for 'fr-FR': vrai +// Value for 'ru-RU': верно +// diff --git a/snippets/csharp/System/Boolean/Overview/operations1.cs b/snippets/csharp/System/Boolean/Overview/operations1.cs new file mode 100644 index 00000000000..bd47be79043 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/operations1.cs @@ -0,0 +1,91 @@ +// +using System; +using System.IO; +using System.Threading; + +public class Example5 +{ + public static void Main() + { + // Initialize flag variables. + bool isRedirected = false; + bool isBoth = false; + String fileName = ""; + StreamWriter sw = null; + + // Get any command line arguments. + String[] args = Environment.GetCommandLineArgs(); + // Handle any arguments. + if (args.Length > 1) { + for (int ctr = 1; ctr < args.Length; ctr++) { + String arg = args[ctr]; + if (arg.StartsWith("/") || arg.StartsWith("-")) { + switch (arg.Substring(1).ToLower()) + { + case "f": + isRedirected = true; + if (args.Length < ctr + 2) { + ShowSyntax("The /f switch must be followed by a filename."); + return; + } + fileName = args[ctr + 1]; + ctr++; + break; + case "b": + isBoth = true; + break; + default: + ShowSyntax(String.Format("The {0} switch is not supported", + args[ctr])); + return; + } + } + } + } + + // If isBoth is True, isRedirected must be True. + if (isBoth && ! isRedirected) { + ShowSyntax("The /f switch must be used if /b is used."); + return; + } + + // Handle output. + if (isRedirected) { + sw = new StreamWriter(fileName); + if (!isBoth) Console.SetOut(sw); + } + String msg = String.Format("Application began at {0}", DateTime.Now); + Console.WriteLine(msg); + if (isBoth) sw.WriteLine(msg); + Thread.Sleep(5000); + msg = String.Format("Application ended normally at {0}", DateTime.Now); + Console.WriteLine(msg); + if (isBoth) sw.WriteLine(msg); + if (isRedirected) sw.Close(); + } + + private static void ShowSyntax(String errMsg) + { + Console.WriteLine(errMsg); + Console.WriteLine("\nSyntax: Example [[/f [/b]]\n"); + } +} +// + +public class Evaluation +{ + public void SomeMethod() + { + bool booleanValue = false; + + // + if (booleanValue == true) { + // + } + + // + if (booleanValue) { + // + } + } +} diff --git a/snippets/csharp/System/Boolean/Overview/operations2.cs b/snippets/csharp/System/Boolean/Overview/operations2.cs new file mode 100644 index 00000000000..d64b1de0602 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/operations2.cs @@ -0,0 +1,23 @@ +// +using System; + +public class Example6 +{ + public static void Main() + { + bool[] hasServiceCharges = { true, false }; + Decimal subtotal = 120.62m; + Decimal shippingCharge = 2.50m; + Decimal serviceCharge = 5.00m; + + foreach (var hasServiceCharge in hasServiceCharges) { + Decimal total = subtotal + shippingCharge + + (hasServiceCharge ? serviceCharge : 0); + Console.WriteLine($"hasServiceCharge = {hasServiceCharge}: The total is {total:C2}."); + } + } +} +// The example displays output like the following: +// hasServiceCharge = True: The total is $128.12. +// hasServiceCharge = False: The total is $123.12. +// diff --git a/snippets/csharp/System/Boolean/Overview/parse2.cs b/snippets/csharp/System/Boolean/Overview/parse2.cs new file mode 100644 index 00000000000..9ab8deea0c0 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/parse2.cs @@ -0,0 +1,66 @@ +// +using System; + +public class Example7 +{ + public static void Main() + { + string[] values = [ null, String.Empty, "True", "False", + "true", "false", " true ", + "TrUe", "fAlSe", "fa lse", "0", + "1", "-1", "string" ]; + // Parse strings using the Boolean.Parse method. + foreach (var value in values) { + try { + bool flag = Boolean.Parse(value); + Console.WriteLine($"'{value}' --> {flag}"); + } + catch (ArgumentException) { + Console.WriteLine("Cannot parse a null string."); + } + catch (FormatException) { + Console.WriteLine($"Cannot parse '{value}'."); + } + } + Console.WriteLine(); + // Parse strings using the Boolean.TryParse method. + foreach (var value in values) { + bool flag = false; + if (Boolean.TryParse(value, out flag)) + Console.WriteLine($"'{value}' --> {flag}"); + else + Console.WriteLine($"Unable to parse '{value}'"); + } + } +} +// The example displays the following output: +// Cannot parse a null string. +// Cannot parse ''. +// 'True' --> True +// 'False' --> False +// 'true' --> True +// 'false' --> False +// ' true ' --> True +// 'TrUe' --> True +// 'fAlSe' --> False +// Cannot parse 'fa lse'. +// Cannot parse '0'. +// Cannot parse '1'. +// Cannot parse '-1'. +// Cannot parse 'string'. +// +// Unable to parse '' +// Unable to parse '' +// 'True' --> True +// 'False' --> False +// 'true' --> True +// 'false' --> False +// ' true ' --> True +// 'TrUe' --> True +// 'fAlSe' --> False +// Cannot parse 'fa lse'. +// Unable to parse '0' +// Unable to parse '1' +// Unable to parse '-1' +// Unable to parse 'string' +// diff --git a/snippets/csharp/System/Boolean/Overview/parse3.cs b/snippets/csharp/System/Boolean/Overview/parse3.cs new file mode 100644 index 00000000000..48d7a9f08fd --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/parse3.cs @@ -0,0 +1,29 @@ +// +using System; + +public class Example8 +{ + public static void Main() + { + String[] values = [ "09", "12.6", "0", "-13 " ]; + foreach (var value in values) { + bool success, result; + int number; + success = Int32.TryParse(value, out number); + if (success) { + // The method throws no exceptions. + result = Convert.ToBoolean(number); + Console.WriteLine($"Converted '{value}' to {result}"); + } + else { + Console.WriteLine($"Unable to convert '{value}'"); + } + } + } +} +// The example displays the following output: +// Converted '09' to True +// Unable to convert '12.6' +// Converted '0' to False +// Converted '-13 ' to True +// diff --git a/snippets/csharp/System/Boolean/Overview/size1.cs b/snippets/csharp/System/Boolean/Overview/size1.cs new file mode 100644 index 00000000000..2e145259d26 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/size1.cs @@ -0,0 +1,38 @@ +// +using System; + +public struct BoolStruct +{ + public bool flag1; + public bool flag2; + public bool flag3; + public bool flag4; + public bool flag5; +} + +public class Example9 +{ + public static void Main() + { + unsafe { + BoolStruct b = new BoolStruct(); + bool* addr = (bool*) &b; + Console.WriteLine($"Size of BoolStruct: {sizeof(BoolStruct)}"); + Console.WriteLine("Field offsets:"); + Console.WriteLine($" flag1: {(bool*) &b.flag1 - addr}"); + Console.WriteLine($" flag2: {(bool*) &b.flag2 - addr}"); + Console.WriteLine($" flag3: {(bool*) &b.flag3 - addr}"); + Console.WriteLine($" flag4: {(bool*) &b.flag4 - addr}"); + Console.WriteLine($" flag5: {(bool*) &b.flag5 - addr}"); + } + } +} +// The example displays the following output: +// Size of BoolStruct: 5 +// Field offsets: +// flag1: 0 +// flag2: 1 +// flag3: 2 +// flag4: 3 +// flag5: 4 +// diff --git a/snippets/csharp/System/Boolean/Overview/tostring1.cs b/snippets/csharp/System/Boolean/Overview/tostring1.cs new file mode 100644 index 00000000000..09cfd324cd8 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/tostring1.cs @@ -0,0 +1,18 @@ +// +using System; + +public class Example10 +{ + public static void Main() + { + bool raining = false; + bool busLate = true; + + Console.WriteLine($"It is raining: {raining}"); + Console.WriteLine($"The bus is late: {busLate}"); + } +} +// The example displays the following output: +// It is raining: False +// The bus is late: True +// diff --git a/snippets/csharp/System/Boolean/Overview/tostring2.cs b/snippets/csharp/System/Boolean/Overview/tostring2.cs new file mode 100644 index 00000000000..c691140aa05 --- /dev/null +++ b/snippets/csharp/System/Boolean/Overview/tostring2.cs @@ -0,0 +1,18 @@ +// +using System; + +public class Example11 +{ + public static void Main() + { + bool raining = false; + bool busLate = true; + + Console.WriteLine($"It is raining: {(raining ? "Yes" : "No")}"); + Console.WriteLine($"The bus is late: {(busLate ? "Yes" : "No")}"); + } +} +// The example displays the following output: +// It is raining: No +// The bus is late: Yes +// diff --git a/snippets/csharp/System/Byte/Overview/Project.csproj b/snippets/csharp/System/Byte/Overview/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Byte/Overview/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Byte/Overview/ToByte5.cs b/snippets/csharp/System/Byte/Overview/ToByte5.cs index 0e5ac722d15..74f608ed14a 100644 --- a/snippets/csharp/System/Byte/Overview/ToByte5.cs +++ b/snippets/csharp/System/Byte/Overview/ToByte5.cs @@ -1,7 +1,7 @@ // using System; -public class Example +public class Example5 { public static void Main() { diff --git a/snippets/csharp/System/Byte/Overview/bitwise1.cs b/snippets/csharp/System/Byte/Overview/bitwise1.cs new file mode 100644 index 00000000000..b3266d2482e --- /dev/null +++ b/snippets/csharp/System/Byte/Overview/bitwise1.cs @@ -0,0 +1,24 @@ +// +using System; +using System.Globalization; + +public class Example +{ + public static void Main() + { + string[] values = [ Convert.ToString(12, 16), + Convert.ToString(123, 16), + Convert.ToString(245, 16) ]; + + byte mask = 0xFE; + foreach (string value in values) { + Byte byteValue = Byte.Parse(value, NumberStyles.AllowHexSpecifier); + Console.WriteLine($"{byteValue} And {mask} = {byteValue & mask}"); + } + } +} +// The example displays the following output: +// 12 And 254 = 12 +// 123 And 254 = 122 +// 245 And 254 = 244 +// diff --git a/snippets/csharp/System/Byte/Overview/bitwise2.cs b/snippets/csharp/System/Byte/Overview/bitwise2.cs new file mode 100644 index 00000000000..685c2f82f34 --- /dev/null +++ b/snippets/csharp/System/Byte/Overview/bitwise2.cs @@ -0,0 +1,49 @@ +// +using System; +using System.Collections.Generic; +using System.Globalization; + +public struct ByteString +{ + public string Value; + public int Sign; +} + +public class BSExample1 +{ + public static void Main() + { + ByteString[] values = CreateArray(-15, 123, 245); + + byte mask = 0x14; // Mask all bits but 2 and 4. + + foreach (ByteString strValue in values) + { + byte byteValue = Byte.Parse(strValue.Value, NumberStyles.AllowHexSpecifier); + Console.WriteLine($"{strValue.Sign * byteValue} ({Convert.ToString(byteValue, 2)}) And {mask} ({Convert.ToString(mask, 2)}) = {(strValue.Sign & Math.Sign(mask)) * (byteValue & mask)} ({Convert.ToString(byteValue & mask, 2)})"); + } + } + + private static ByteString[] CreateArray(params int[] values) + { + List byteStrings = new(); + + foreach (object value in values) + { + ByteString temp = new ByteString(); + int sign = Math.Sign((int)value); + temp.Sign = sign; + + // Change two's complement to magnitude-only representation. + temp.Value = Convert.ToString(((int)value) * sign, 16); + + byteStrings.Add(temp); + } + return byteStrings.ToArray(); + } +} +// The example displays the following output: +// -15 (1111) And 20 (10100) = 4 (100) +// 123 (1111011) And 20 (10100) = 16 (10000) +// 245 (11110101) And 20 (10100) = 20 (10100) +// diff --git a/snippets/csharp/System/Byte/Overview/byteinstantiation1.cs b/snippets/csharp/System/Byte/Overview/byteinstantiation1.cs new file mode 100644 index 00000000000..ef7211fc761 --- /dev/null +++ b/snippets/csharp/System/Byte/Overview/byteinstantiation1.cs @@ -0,0 +1,89 @@ +using System; + +public class BIExample1 +{ + public static void Main() + { + InstantiateByAssignment(); + InstantiateByNarrowingConversion(); + Parse(); + } + + private static void InstantiateByAssignment() + { + // + byte value1 = 64; + byte value2 = 255; + // + Console.WriteLine($"{value1} {value2}"); + } + + private static void InstantiateByNarrowingConversion() + { + // + int int1 = 128; + try + { + byte value1 = (byte)int1; + Console.WriteLine(value1); + } + catch (OverflowException) + { + Console.WriteLine($"{int1} is out of range of a byte."); + } + + double dbl2 = 3.997; + try + { + byte value2 = (byte)dbl2; + Console.WriteLine(value2); + } + catch (OverflowException) + { + Console.WriteLine($"{dbl2} is out of range of a byte."); + } + // The example displays the following output: + // 128 + // 3 + // + } + + private static void Parse() + { + // + string string1 = "244"; + try + { + byte byte1 = Byte.Parse(string1); + Console.WriteLine(byte1); + } + catch (OverflowException) + { + Console.WriteLine($"'{string1}' is out of range of a byte."); + } + catch (FormatException) + { + Console.WriteLine($"'{string1}' is out of range of a byte."); + } + + string string2 = "F9"; + try + { + byte byte2 = Byte.Parse(string2, + System.Globalization.NumberStyles.HexNumber); + Console.WriteLine(byte2); + } + catch (OverflowException) + { + Console.WriteLine($"'{string2}' is out of range of a byte."); + } + catch (FormatException) + { + Console.WriteLine($"'{string2}' is out of range of a byte."); + } + // The example displays the following output: + // 244 + // 249 + // + } +} diff --git a/snippets/csharp/System/Byte/Overview/formatting1.cs b/snippets/csharp/System/Byte/Overview/formatting1.cs new file mode 100644 index 00000000000..6f4d4710187 --- /dev/null +++ b/snippets/csharp/System/Byte/Overview/formatting1.cs @@ -0,0 +1,56 @@ +using System; + +public class FormattingExample +{ + public static void Main() + { + CallToString(); + Console.WriteLine("-----"); + CallConvert(); + } + + private static void CallToString() + { + // + byte[] numbers = [ 0, 16, 104, 213 ]; + foreach (byte number in numbers) + { + // Display value using default formatting. + Console.Write("{0,-3} --> ", number.ToString()); + // Display value with 3 digits and leading zeros. + Console.Write(number.ToString("D3") + " "); + // Display value with hexadecimal. + Console.Write(number.ToString("X2") + " "); + // Display value with four hexadecimal digits. + Console.WriteLine(number.ToString("X4")); + } + // The example displays the following output: + // 0 --> 000 00 0000 + // 16 --> 016 10 0010 + // 104 --> 104 68 0068 + // 213 --> 213 D5 00D5 + // + } + + private static void CallConvert() + { + // + byte[] numbers = { 0, 16, 104, 213 }; + Console.WriteLine("{0} {1,8} {2,5} {3,5}", + "Value", "Binary", "Octal", "Hex"); + foreach (byte number in numbers) + { + Console.WriteLine("{0,5} {1,8} {2,5} {3,5}", + number, Convert.ToString(number, 2), + Convert.ToString(number, 8), + Convert.ToString(number, 16)); + } + // The example displays the following output: + // Value Binary Octal Hex + // 0 0 0 0 + // 16 10000 20 10 + // 104 1101000 150 68 + // 213 11010101 325 d5 + // + } +} diff --git a/snippets/csharp/System/Byte/Overview/tobyte1.cs b/snippets/csharp/System/Byte/Overview/tobyte1.cs index 4dc5375b102..bc260436d8c 100644 --- a/snippets/csharp/System/Byte/Overview/tobyte1.cs +++ b/snippets/csharp/System/Byte/Overview/tobyte1.cs @@ -1,6 +1,6 @@ using System; -public class Example +public class Example1 { public static void Main() { diff --git a/snippets/csharp/System/Byte/Overview/tobyte2.cs b/snippets/csharp/System/Byte/Overview/tobyte2.cs index e9116c90e10..19b5a2296c8 100644 --- a/snippets/csharp/System/Byte/Overview/tobyte2.cs +++ b/snippets/csharp/System/Byte/Overview/tobyte2.cs @@ -1,7 +1,7 @@ // using System; -public class Example +public class Example2 { public static void Main() { @@ -32,6 +32,7 @@ public static void Main() } } } + // The example displays the following output: // Base 2: // '-1' is invalid in base 2. diff --git a/snippets/csharp/System/Byte/Overview/tobyte3.cs b/snippets/csharp/System/Byte/Overview/tobyte3.cs index 26757c2fe25..037bb62aa29 100644 --- a/snippets/csharp/System/Byte/Overview/tobyte3.cs +++ b/snippets/csharp/System/Byte/Overview/tobyte3.cs @@ -4,7 +4,7 @@ public enum SignBit { Negative=-1, Zero=0, Positive=1 }; -public struct ByteString : IConvertible +public struct ByteString3 : IConvertible { private SignBit signBit; private string byteString; @@ -60,7 +60,7 @@ public char ToChar(IFormatProvider provider) public DateTime ToDateTime(IFormatProvider provider) { - throw new InvalidCastException("ByteString to DateTime conversion is not supported."); + throw new InvalidCastException("ByteString3 to DateTime conversion is not supported."); } public decimal ToDecimal(IFormatProvider provider) @@ -159,7 +159,7 @@ public object ToType(Type conversionType, IFormatProvider provider) case TypeCode.Int64: return this.ToInt64(null); case TypeCode.Object: - if (typeof(ByteString).Equals(conversionType)) + if (typeof(ByteString3).Equals(conversionType)) return this; else throw new InvalidCastException(String.Format("Conversion to a {0} is not supported.", conversionType.Name)); @@ -217,11 +217,11 @@ public static void Main() byte positiveByte = 216; sbyte negativeByte = -101; - ByteString positiveString = new ByteString(); + ByteString3 positiveString = new ByteString3(); positiveString.Sign = (SignBit) Math.Sign(positiveByte); positiveString.Value = positiveByte.ToString("X2"); - ByteString negativeString = new ByteString(); + ByteString3 negativeString = new ByteString3(); negativeString.Sign = (SignBit) Math.Sign(negativeByte); negativeString.Value = negativeByte.ToString("X2"); diff --git a/snippets/csharp/System/Byte/Overview/tobyte4.cs b/snippets/csharp/System/Byte/Overview/tobyte4.cs index 1d5c590801e..cb1ef5c8c9c 100644 --- a/snippets/csharp/System/Byte/Overview/tobyte4.cs +++ b/snippets/csharp/System/Byte/Overview/tobyte4.cs @@ -2,7 +2,7 @@ using System; using System.Globalization; -public class Example +public class Example4 { public static void Main() { diff --git a/snippets/csharp/System/Char/Overview/GetUnicodeCategory3.cs b/snippets/csharp/System/Char/Overview/GetUnicodeCategory3.cs new file mode 100644 index 00000000000..a41456fc514 --- /dev/null +++ b/snippets/csharp/System/Char/Overview/GetUnicodeCategory3.cs @@ -0,0 +1,72 @@ +// +using System; +using System.Globalization; + +class Example +{ + public static void Main() + { + // Define a string with a variety of character categories. + String s = "The red car drove down the long, narrow, secluded road."; + // Determine the category of each character. + foreach (var ch in s) + Console.WriteLine($"'{ch}': {Char.GetUnicodeCategory(ch)}"); + } +} +// The example displays the following output: +// 'T': UppercaseLetter +// 'h': LowercaseLetter +// 'e': LowercaseLetter +// ' ': SpaceSeparator +// 'r': LowercaseLetter +// 'e': LowercaseLetter +// 'd': LowercaseLetter +// ' ': SpaceSeparator +// 'c': LowercaseLetter +// 'a': LowercaseLetter +// 'r': LowercaseLetter +// ' ': SpaceSeparator +// 'd': LowercaseLetter +// 'r': LowercaseLetter +// 'o': LowercaseLetter +// 'v': LowercaseLetter +// 'e': LowercaseLetter +// ' ': SpaceSeparator +// 'd': LowercaseLetter +// 'o': LowercaseLetter +// 'w': LowercaseLetter +// 'n': LowercaseLetter +// ' ': SpaceSeparator +// 't': LowercaseLetter +// 'h': LowercaseLetter +// 'e': LowercaseLetter +// ' ': SpaceSeparator +// 'l': LowercaseLetter +// 'o': LowercaseLetter +// 'n': LowercaseLetter +// 'g': LowercaseLetter +// ',': OtherPunctuation +// ' ': SpaceSeparator +// 'n': LowercaseLetter +// 'a': LowercaseLetter +// 'r': LowercaseLetter +// 'r': LowercaseLetter +// 'o': LowercaseLetter +// 'w': LowercaseLetter +// ',': OtherPunctuation +// ' ': SpaceSeparator +// 's': LowercaseLetter +// 'e': LowercaseLetter +// 'c': LowercaseLetter +// 'l': LowercaseLetter +// 'u': LowercaseLetter +// 'd': LowercaseLetter +// 'e': LowercaseLetter +// 'd': LowercaseLetter +// ' ': SpaceSeparator +// 'r': LowercaseLetter +// 'o': LowercaseLetter +// 'a': LowercaseLetter +// 'd': LowercaseLetter +// '.': OtherPunctuation +// diff --git a/snippets/csharp/System/Char/Overview/Project.csproj b/snippets/csharp/System/Char/Overview/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Char/Overview/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Char/Overview/grapheme1.cs b/snippets/csharp/System/Char/Overview/grapheme1.cs new file mode 100644 index 00000000000..3282858b551 --- /dev/null +++ b/snippets/csharp/System/Char/Overview/grapheme1.cs @@ -0,0 +1,18 @@ +// +using System; +using System.IO; + +public class Example1 +{ + public static void Main() + { + StreamWriter sw = new StreamWriter("chars1.txt"); + char[] chars = [ '\u0061', '\u0308' ]; + string strng = new String(chars); + sw.WriteLine(strng); + sw.Close(); + } +} +// The example produces the following output: +// ä +// diff --git a/snippets/csharp/System/Char/Overview/normalized.cs b/snippets/csharp/System/Char/Overview/normalized.cs new file mode 100644 index 00000000000..899b22591c7 --- /dev/null +++ b/snippets/csharp/System/Char/Overview/normalized.cs @@ -0,0 +1,30 @@ +// +using System; + +public class Example2 +{ + public static void Main() + { + string combining = "\u0061\u0308"; + ShowString(combining); + + string normalized = combining.Normalize(); + ShowString(normalized); + } + + private static void ShowString(string s) + { + Console.Write($"Length of string: {s.Length} ("); + for (int ctr = 0; ctr < s.Length; ctr++) + { + Console.Write($"U+{Convert.ToUInt16(s[ctr]):X4}"); + if (ctr != s.Length - 1) Console.Write(" "); + } + Console.WriteLine(")\n"); + } +} +// The example displays the following output: +// Length of string: 2 (U+0061 U+0308) +// +// Length of string: 1 (U+00E4) +// diff --git a/snippets/csharp/System/Char/Overview/surrogate1.cs b/snippets/csharp/System/Char/Overview/surrogate1.cs new file mode 100644 index 00000000000..767c0443120 --- /dev/null +++ b/snippets/csharp/System/Char/Overview/surrogate1.cs @@ -0,0 +1,27 @@ +// +using System; +using System.IO; + +public class Example3 +{ + public static void Main() + { + StreamWriter sw = new StreamWriter(@".\chars2.txt"); + int utf32 = 0x1D160; + string surrogate = Char.ConvertFromUtf32(utf32); + sw.WriteLine($"U+{utf32:X6} UTF-32 = {surrogate} ({ShowCodePoints(surrogate)}) UTF-16"); + sw.Close(); + } + + private static string ShowCodePoints(string value) + { + string retval = null; + foreach (var ch in value) + retval += $"U+{Convert.ToUInt16(ch):X4} "; + + return retval.Trim(); + } +} +// The example produces the following output: +// U+01D160 UTF-32 = ð (U+D834 U+DD60) UTF-16 +// diff --git a/snippets/csharp/System/Char/Overview/textelements2.cs b/snippets/csharp/System/Char/Overview/textelements2.cs new file mode 100644 index 00000000000..c039c618373 --- /dev/null +++ b/snippets/csharp/System/Char/Overview/textelements2.cs @@ -0,0 +1,17 @@ +// +using System; + +public class Example5 +{ + public static void Main() + { + string result = String.Empty; + for (int ctr = 0x10107; ctr <= 0x10110; ctr++) // Range of Aegean numbers. + result += Char.ConvertFromUtf32(ctr); + + Console.WriteLine($"The string contains {result.Length} characters."); + } +} +// The example displays the following output: +// The string contains 20 characters. +// diff --git a/snippets/csharp/System/Char/Overview/textelements2a.cs b/snippets/csharp/System/Char/Overview/textelements2a.cs new file mode 100644 index 00000000000..e6bcb56f7d7 --- /dev/null +++ b/snippets/csharp/System/Char/Overview/textelements2a.cs @@ -0,0 +1,19 @@ +// +using System; +using System.Globalization; + +public class Example4 +{ + public static void Main() + { + string result = String.Empty; + for (int ctr = 0x10107; ctr <= 0x10110; ctr++) // Range of Aegean numbers. + result += Char.ConvertFromUtf32(ctr); + + StringInfo si = new StringInfo(result); + Console.WriteLine($"The string contains {si.LengthInTextElements} characters."); + } +} +// The example displays the following output: +// The string contains 10 characters. +// diff --git a/snippets/csharp/System/DateTime/FromBinary/frombinary1.cs b/snippets/csharp/System/DateTime/FromBinary/frombinary1.cs new file mode 100644 index 00000000000..9de79296a2e --- /dev/null +++ b/snippets/csharp/System/DateTime/FromBinary/frombinary1.cs @@ -0,0 +1,20 @@ +// +using System; + +public class Example +{ + public static void Main() + { + DateTime localDate = new (2010, 3, 14, 2, 30, 0, DateTimeKind.Local); + long binLocal = localDate.ToBinary(); + if (TimeZoneInfo.Local.IsInvalidTime(localDate)) + Console.WriteLine($"{localDate} is an invalid time in the {TimeZoneInfo.Local.StandardName} zone."); + + DateTime localDate2 = DateTime.FromBinary(binLocal); + Console.WriteLine($"{localDate} = {localDate2}: {localDate.Equals(localDate2)}"); + } +} +// The example displays the following output: +// 3/14/2010 2:30:00 AM is an invalid time in the Pacific Standard Time zone. +// 3/14/2010 2:30:00 AM = 3/14/2010 3:30:00 AM: False +// diff --git a/snippets/csharp/System/DateTime/Overview/Calendar.cs b/snippets/csharp/System/DateTime/Overview/Calendar.cs new file mode 100644 index 00000000000..09845d52328 --- /dev/null +++ b/snippets/csharp/System/DateTime/Overview/Calendar.cs @@ -0,0 +1,117 @@ +using System; + +namespace SystemDateTimeReference +{ + public static class CalendarSamples + { + public static void Snippets() + { + ThaiBuddistEra(); + ThaiBuddhistEraParse(); + InstantiateCalendar(); + CalendarFields(); + CalculateWeeks(); + } + + private static void ThaiBuddistEra() + { + // + var thTH = new System.Globalization.CultureInfo("th-TH"); + var value = new DateTime(2016, 5, 28); + + Console.WriteLine(value.ToString(thTH)); + + thTH.DateTimeFormat.Calendar = new System.Globalization.GregorianCalendar(); + Console.WriteLine(value.ToString(thTH)); + // The example displays the following output: + // 28/5/2559 0:00:00 + // 28/5/2016 0:00:00 + // + } + + private static void ThaiBuddhistEraParse() + { + // + var thTH = new System.Globalization.CultureInfo("th-TH"); + var value = DateTime.Parse("28/05/2559", thTH); + Console.WriteLine(value.ToString(thTH)); + + thTH.DateTimeFormat.Calendar = new System.Globalization.GregorianCalendar(); + Console.WriteLine(value.ToString(thTH)); + // The example displays the following output: + // 28/5/2559 0:00:00 + // 28/5/2016 0:00:00 + // + } + + private static void InstantiateCalendar() + { + // + var thTH = new System.Globalization.CultureInfo("th-TH"); + var dat = new DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar); + Console.WriteLine($"Thai Buddhist era date: {dat.ToString("d", thTH)}"); + Console.WriteLine($"Gregorian date: {dat:d}"); + // The example displays the following output: + // Thai Buddhist Era Date: 28/5/2559 + // Gregorian Date: 28/05/2016 + // + } + + private static void CalendarFields() + { + // + var thTH = new System.Globalization.CultureInfo("th-TH"); + var cal = thTH.DateTimeFormat.Calendar; + var dat = new DateTime(2559, 5, 28, cal); + Console.WriteLine("Using the Thai Buddhist Era calendar:"); + Console.WriteLine($"Date: {dat.ToString("d", thTH)}"); + Console.WriteLine($"Year: {cal.GetYear(dat)}"); + Console.WriteLine($"Leap year: {cal.IsLeapYear(cal.GetYear(dat))}\n"); + + Console.WriteLine("Using the Gregorian calendar:"); + Console.WriteLine($"Date: {dat:d}"); + Console.WriteLine($"Year: {dat.Year}"); + Console.WriteLine($"Leap year: {DateTime.IsLeapYear(dat.Year)}"); + // The example displays the following output: + // Using the Thai Buddhist Era calendar + // Date : 28/5/2559 + // Year: 2559 + // Leap year : True + // + // Using the Gregorian calendar + // Date : 28/05/2016 + // Year: 2016 + // Leap year : True + // + } + + private static void CalculateWeeks() + { + // + var thTH = new System.Globalization.CultureInfo("th-TH"); + var thCalendar = thTH.DateTimeFormat.Calendar; + var dat = new DateTime(1395, 8, 18, thCalendar); + Console.WriteLine("Using the Thai Buddhist Era calendar:"); + Console.WriteLine($"Date: {dat.ToString("d", thTH)}"); + Console.WriteLine($"Day of Week: {thCalendar.GetDayOfWeek(dat)}"); + Console.WriteLine($"Week of year: {thCalendar.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}\n"); + + var greg = new System.Globalization.GregorianCalendar(); + Console.WriteLine("Using the Gregorian calendar:"); + Console.WriteLine($"Date: {dat:d}"); + Console.WriteLine($"Day of Week: {dat.DayOfWeek}"); + Console.WriteLine($"Week of year: {greg.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay,DayOfWeek.Sunday)}"); + // The example displays the following output: + // Using the Thai Buddhist Era calendar + // Date : 18/8/1395 + // Day of Week: Sunday + // Week of year: 34 + // + // Using the Gregorian calendar + // Date : 18/08/0852 + // Day of Week: Sunday + // Week of year: 34 + // + } + } +} diff --git a/snippets/csharp/System/DateTime/Overview/DateTimeComparisons.cs b/snippets/csharp/System/DateTime/Overview/DateTimeComparisons.cs new file mode 100644 index 00000000000..b7342dbee56 --- /dev/null +++ b/snippets/csharp/System/DateTime/Overview/DateTimeComparisons.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SystemDateTimeReference +{ + public static class DateTimeComparisons + { + public static void Snippets() + { + TestRoughlyEquals(); + } + + // + public static bool RoughlyEquals(DateTime time, DateTime timeWithWindow, int windowInSeconds, int frequencyInSeconds) + { + long delta = (long)((TimeSpan)(timeWithWindow - time)).TotalSeconds % frequencyInSeconds; + delta = delta > windowInSeconds ? frequencyInSeconds - delta : delta; + return Math.Abs(delta) < windowInSeconds; + } + + public static void TestRoughlyEquals() + { + int window = 10; + int freq = 60 * 60 * 2; // 2 hours; + + DateTime d1 = DateTime.Now; + + DateTime d2 = d1.AddSeconds(2 * window); + DateTime d3 = d1.AddSeconds(-2 * window); + DateTime d4 = d1.AddSeconds(window / 2); + DateTime d5 = d1.AddSeconds(-window / 2); + + DateTime d6 = (d1.AddHours(2)).AddSeconds(2 * window); + DateTime d7 = (d1.AddHours(2)).AddSeconds(-2 * window); + DateTime d8 = (d1.AddHours(2)).AddSeconds(window / 2); + DateTime d9 = (d1.AddHours(2)).AddSeconds(-window / 2); + + Console.WriteLine($"d1 ({d1}) ~= d1 ({d1}): {RoughlyEquals(d1, d1, window, freq)}"); + Console.WriteLine($"d1 ({d1}) ~= d2 ({d2}): {RoughlyEquals(d1, d2, window, freq)}"); + Console.WriteLine($"d1 ({d1}) ~= d3 ({d3}): {RoughlyEquals(d1, d3, window, freq)}"); + Console.WriteLine($"d1 ({d1}) ~= d4 ({d4}): {RoughlyEquals(d1, d4, window, freq)}"); + Console.WriteLine($"d1 ({d1}) ~= d5 ({d5}): {RoughlyEquals(d1, d5, window, freq)}"); + + Console.WriteLine($"d1 ({d1}) ~= d6 ({d6}): {RoughlyEquals(d1, d6, window, freq)}"); + Console.WriteLine($"d1 ({d1}) ~= d7 ({d7}): {RoughlyEquals(d1, d7, window, freq)}"); + Console.WriteLine($"d1 ({d1}) ~= d8 ({d8}): {RoughlyEquals(d1, d8, window, freq)}"); + Console.WriteLine($"d1 ({d1}) ~= d9 ({d9}): {RoughlyEquals(d1, d9, window, freq)}"); + } + // The example displays output similar to the following: + // d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True + // d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False + // d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False + // d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True + // d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True + // d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False + // d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False + // d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True + // d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True + // + } +} diff --git a/snippets/csharp/System/DateTime/Overview/Instantiation.cs b/snippets/csharp/System/DateTime/Overview/Instantiation.cs new file mode 100644 index 00000000000..0b833830532 --- /dev/null +++ b/snippets/csharp/System/DateTime/Overview/Instantiation.cs @@ -0,0 +1,55 @@ +using System; + +namespace SystemDateTimeReference +{ + public static class Instantiation + { + public static void Snippets() + { + InstantiateWithConstructor(); + InstantiateWithReturnValue(); + InstantiateFromString(); + InstantiateUsingDftCtor(); + } + + private static void InstantiateWithConstructor() + { + // + var date1 = new DateTime(2008, 5, 1, 8, 30, 52); + Console.WriteLine(date1); + // + } + + private static void InstantiateWithReturnValue() + { + // + DateTime date1 = DateTime.Now; + DateTime date2 = DateTime.UtcNow; + DateTime date3 = DateTime.Today; + // + } + + private static void InstantiateFromString() + { + // + var dateString = "5/1/2008 8:30:52 AM"; + DateTime date1 = DateTime.Parse(dateString, + System.Globalization.CultureInfo.InvariantCulture); + var iso8601String = "20080501T08:30:52Z"; + DateTime dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", + System.Globalization.CultureInfo.InvariantCulture); + // + } + + private static void InstantiateUsingDftCtor() + { + // + var dat1 = new DateTime(); + // The following method call displays 1/1/0001 12:00:00 AM. + Console.WriteLine(dat1.ToString(System.Globalization.CultureInfo.InvariantCulture)); + // The following method call displays True. + Console.WriteLine(dat1.Equals(DateTime.MinValue)); + // + } + } +} diff --git a/snippets/csharp/System/DateTime/Overview/Parsing.cs b/snippets/csharp/System/DateTime/Overview/Parsing.cs new file mode 100644 index 00000000000..d202ca61f61 --- /dev/null +++ b/snippets/csharp/System/DateTime/Overview/Parsing.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; + +namespace SystemDateTimeReference +{ + public static class Parsing + { + public static void Snippets() + { + ParseStandardFormats(); + ParseCustomFormats(); + ParseISO8601(); + } + + private static void ParseStandardFormats() + { + // + System.Threading.Thread.CurrentThread.CurrentCulture = + System.Globalization.CultureInfo.CreateSpecificCulture("en-GB"); + + var date1 = new DateTime(2013, 6, 1, 12, 32, 30); + var badFormats = new List(); + + Console.WriteLine($"{"Date String",-37} {"Date",-19}\n"); + foreach (var dateString in date1.GetDateTimeFormats()) + { + DateTime parsedDate; + if (DateTime.TryParse(dateString, out parsedDate)) + Console.WriteLine($"{dateString,-37} {DateTime.Parse(dateString),-19}"); + else + badFormats.Add(dateString); + } + + // Display strings that could not be parsed. + if (badFormats.Count > 0) + { + Console.WriteLine("\nStrings that could not be parsed: "); + foreach (var badFormat in badFormats) + Console.WriteLine($" {badFormat}"); + } + // Press "Run" to see the output. + // + } + + private static void ParseCustomFormats() + { + // + string[] formats = { "yyyyMMdd", "HHmmss" }; + string[] dateStrings = { "20130816", "20131608", " 20130816 ", + "115216", "521116", " 115216 " }; + DateTime parsedDate; + + foreach (var dateString in dateStrings) + { + if (DateTime.TryParseExact(dateString, formats, null, + System.Globalization.DateTimeStyles.AllowWhiteSpaces | + System.Globalization.DateTimeStyles.AdjustToUniversal, + out parsedDate)) + Console.WriteLine($"{dateString} --> {parsedDate:g}"); + else + Console.WriteLine($"Cannot convert {dateString}"); + } + // The example displays the following output: + // 20130816 --> 8/16/2013 12:00 AM + // Cannot convert 20131608 + // 20130816 --> 8/16/2013 12:00 AM + // 115216 --> 4/22/2013 11:52 AM + // Cannot convert 521116 + // 115216 --> 4/22/2013 11:52 AM + // + } + private static void ParseISO8601() + { + // + var iso8601String = "20080501T08:30:52Z"; + DateTime dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", + System.Globalization.CultureInfo.InvariantCulture); + Console.WriteLine($"{iso8601String} --> {dateISO8602:g}"); + // + } + } +} diff --git a/snippets/csharp/System/DateTime/Overview/Persistence.cs b/snippets/csharp/System/DateTime/Overview/Persistence.cs new file mode 100644 index 00000000000..6b5630182d7 --- /dev/null +++ b/snippets/csharp/System/DateTime/Overview/Persistence.cs @@ -0,0 +1,345 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Threading; +using System.Xml.Serialization; + +namespace SystemDateTimeReference +{ + public static class Persistence + { + private const string filenameTxt = @".\BadDates.txt"; + + public static void Snippets() + { + File.Delete(filenameTxt); + PersistAsLocalStrings(); + File.Delete(filenameTxt); + PersistAsInvariantStrings(); + File.Delete(filenameTxt); + + File.Delete(filenameInts); + PersistAsIntegers(); + File.Delete(filenameInts); + + File.Delete(filenameXml); + PersistAsXML(); + File.Delete(filenameXml); + } + + // + public static void PersistAsLocalStrings() + { + SaveLocalDatesAsString(); + RestoreLocalDatesFromString(); + } + + private static void SaveLocalDatesAsString() + { + DateTime[] dates = [ new DateTime(2014, 6, 14, 6, 32, 0), + new DateTime(2014, 7, 10, 23, 49, 0), + new DateTime(2015, 1, 10, 1, 16, 0), + new DateTime(2014, 12, 20, 21, 45, 0), + new DateTime(2014, 6, 2, 15, 14, 0) ]; + string? output = null; + + Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"); + Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"); + for (int ctr = 0; ctr < dates.Length; ctr++) + { + Console.WriteLine(dates[ctr].ToString("f")); + output += dates[ctr].ToString() + (ctr != dates.Length - 1 ? "|" : ""); + } + var sw = new StreamWriter(filenameTxt); + sw.Write(output); + sw.Close(); + Console.WriteLine("Saved dates..."); + } + + private static void RestoreLocalDatesFromString() + { + TimeZoneInfo.ClearCachedData(); + Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"); + Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB"); + StreamReader sr = new StreamReader(filenameTxt); + string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' }, + StringSplitOptions.RemoveEmptyEntries); + sr.Close(); + Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"); + foreach (var inputValue in inputValues) + { + DateTime dateValue; + if (DateTime.TryParse(inputValue, out dateValue)) + { + Console.WriteLine($"'{inputValue}' --> {dateValue:f}"); + } + else + { + Console.WriteLine($"Cannot parse '{inputValue}'"); + } + } + Console.WriteLine("Restored dates..."); + } + // When saved on an en-US system, the example displays the following output: + // Current Time Zone: (UTC-08:00) Pacific Time (US & Canada) + // The dates on an en-US system: + // Saturday, June 14, 2014 6:32 AM + // Thursday, July 10, 2014 11:49 PM + // Saturday, January 10, 2015 1:16 AM + // Saturday, December 20, 2014 9:45 PM + // Monday, June 02, 2014 3:14 PM + // Saved dates... + // + // When restored on an en-GB system, the example displays the following output: + // Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London + // The dates on an en-GB system: + // Cannot parse //6/14/2014 6:32:00 AM// + // //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49 + // //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16 + // Cannot parse //12/20/2014 9:45:00 PM// + // //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14 + // Restored dates... + // + + // + public static void PersistAsInvariantStrings() + { + SaveDatesAsInvariantStrings(); + RestoreDatesAsInvariantStrings(); + } + + private static void SaveDatesAsInvariantStrings() + { + DateTime[] dates = [ new DateTime(2014, 6, 14, 6, 32, 0), + new DateTime(2014, 7, 10, 23, 49, 0), + new DateTime(2015, 1, 10, 1, 16, 0), + new DateTime(2014, 12, 20, 21, 45, 0), + new DateTime(2014, 6, 2, 15, 14, 0) ]; + string? output = null; + + Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"); + Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"); + for (int ctr = 0; ctr < dates.Length; ctr++) + { + Console.WriteLine(dates[ctr].ToString("f")); + output += dates[ctr].ToUniversalTime().ToString("O", CultureInfo.InvariantCulture) + + (ctr != dates.Length - 1 ? "|" : ""); + } + var sw = new StreamWriter(filenameTxt); + sw.Write(output); + sw.Close(); + Console.WriteLine("Saved dates..."); + } + + private static void RestoreDatesAsInvariantStrings() + { + TimeZoneInfo.ClearCachedData(); + Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"); + Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB"); + StreamReader sr = new StreamReader(filenameTxt); + string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' }, + StringSplitOptions.RemoveEmptyEntries); + sr.Close(); + Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"); + foreach (var inputValue in inputValues) + { + DateTime dateValue; + if (DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture, + DateTimeStyles.RoundtripKind, out dateValue)) + { + Console.WriteLine($"'{inputValue}' --> {dateValue.ToLocalTime():f}"); + } + else + { + Console.WriteLine($"Cannot parse '{inputValue}'"); + } + } + Console.WriteLine("Restored dates..."); + } + // When saved on an en-US system, the example displays the following output: + // Current Time Zone: (UTC-08:00) Pacific Time (US & Canada) + // The dates on an en-US system: + // Saturday, June 14, 2014 6:32 AM + // Thursday, July 10, 2014 11:49 PM + // Saturday, January 10, 2015 1:16 AM + // Saturday, December 20, 2014 9:45 PM + // Monday, June 02, 2014 3:14 PM + // Saved dates... + // + // When restored on an en-GB system, the example displays the following output: + // Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London + // The dates on an en-GB system: + // '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32 + // '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49 + // '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16 + // '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45 + // '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14 + // Restored dates... + // + + private const string filenameInts = @".\IntDates.bin"; + + // + public static void PersistAsIntegers() + { + SaveDatesAsInts(); + RestoreDatesAsInts(); + } + + private static void SaveDatesAsInts() + { + DateTime[] dates = [ new DateTime(2014, 6, 14, 6, 32, 0), + new DateTime(2014, 7, 10, 23, 49, 0), + new DateTime(2015, 1, 10, 1, 16, 0), + new DateTime(2014, 12, 20, 21, 45, 0), + new DateTime(2014, 6, 2, 15, 14, 0) ]; + + Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"); + Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"); + var ticks = new long[dates.Length]; + for (int ctr = 0; ctr < dates.Length; ctr++) + { + Console.WriteLine(dates[ctr].ToString("f")); + ticks[ctr] = dates[ctr].ToUniversalTime().Ticks; + } + var fs = new FileStream(filenameInts, FileMode.Create); + var bw = new BinaryWriter(fs); + bw.Write(ticks.Length); + foreach (var tick in ticks) + bw.Write(tick); + + bw.Close(); + Console.WriteLine("Saved dates..."); + } + + private static void RestoreDatesAsInts() + { + TimeZoneInfo.ClearCachedData(); + Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"); + Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB"); + FileStream fs = new FileStream(filenameInts, FileMode.Open); + BinaryReader br = new BinaryReader(fs); + int items; + DateTime[] dates; + + try + { + items = br.ReadInt32(); + dates = new DateTime[items]; + + for (int ctr = 0; ctr < items; ctr++) + { + long ticks = br.ReadInt64(); + dates[ctr] = new DateTime(ticks).ToLocalTime(); + } + } + catch (EndOfStreamException) + { + Console.WriteLine("File corruption detected. Unable to restore data..."); + return; + } + catch (IOException) + { + Console.WriteLine("Unspecified I/O error. Unable to restore data..."); + return; + } + // Thrown during array initialization. + catch (OutOfMemoryException) + { + Console.WriteLine("File corruption detected. Unable to restore data..."); + return; + } + finally + { + br.Close(); + } + + Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"); + foreach (var value in dates) + Console.WriteLine(value.ToString("f")); + + Console.WriteLine("Restored dates..."); + } + // When saved on an en-US system, the example displays the following output: + // Current Time Zone: (UTC-08:00) Pacific Time (US & Canada) + // The dates on an en-US system: + // Saturday, June 14, 2014 6:32 AM + // Thursday, July 10, 2014 11:49 PM + // Saturday, January 10, 2015 1:16 AM + // Saturday, December 20, 2014 9:45 PM + // Monday, June 02, 2014 3:14 PM + // Saved dates... + // + // When restored on an en-GB system, the example displays the following output: + // Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London + // The dates on an en-GB system: + // 14 June 2014 14:32 + // 11 July 2014 07:49 + // 10 January 2015 09:16 + // 21 December 2014 05:45 + // 02 June 2014 23:14 + // Restored dates... + // + + private const string filenameXml = @".\LeapYears.xml"; + + // + public static void PersistAsXML() + { + // Serialize the data. + var leapYears = new List(); + for (int year = 2000; year <= 2100; year += 4) + { + if (DateTime.IsLeapYear(year)) + leapYears.Add(new DateTime(year, 2, 29)); + } + DateTime[] dateArray = leapYears.ToArray(); + + var serializer = new XmlSerializer(dateArray.GetType()); + TextWriter sw = new StreamWriter(filenameXml); + + try + { + serializer.Serialize(sw, dateArray); + } + catch (InvalidOperationException e) + { + Console.WriteLine(e.InnerException?.Message); + } + finally + { + if (sw != null) sw.Close(); + } + + // Deserialize the data. + DateTime[]? deserializedDates; + using (var fs = new FileStream(filenameXml, FileMode.Open)) + { + deserializedDates = (DateTime[]?)serializer.Deserialize(fs); + } + + // Display the dates. + Console.WriteLine($"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:"); + int nItems = 0; + if (deserializedDates is not null) + { + foreach (var dat in deserializedDates) + { + Console.Write($" {dat:d} "); + nItems++; + if (nItems % 5 == 0) + Console.WriteLine(); + } + } + } + // The example displays the following output: + // Leap year days from 2000-2100 on an en-GB system: + // 29/02/2000 29/02/2004 29/02/2008 29/02/2012 29/02/2016 + // 29/02/2020 29/02/2024 29/02/2028 29/02/2032 29/02/2036 + // 29/02/2040 29/02/2044 29/02/2048 29/02/2052 29/02/2056 + // 29/02/2060 29/02/2064 29/02/2068 29/02/2072 29/02/2076 + // 29/02/2080 29/02/2084 29/02/2088 29/02/2092 29/02/2096 + // + } +} diff --git a/snippets/csharp/System/DateTime/Overview/Project.csproj b/snippets/csharp/System/DateTime/Overview/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/DateTime/Overview/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/DateTime/Overview/Resolution.cs b/snippets/csharp/System/DateTime/Overview/Resolution.cs new file mode 100644 index 00000000000..987c52284cf --- /dev/null +++ b/snippets/csharp/System/DateTime/Overview/Resolution.cs @@ -0,0 +1,34 @@ +using System; + +namespace SystemDateTimeReference +{ + public static class Resolution + { + public static void Snippets() + { + DemonstrateResolution(); + } + + private static void DemonstrateResolution() + { + // + string output = ""; + for (int ctr = 0; ctr <= 20; ctr++) + { + output += String.Format($"{DateTime.Now.Millisecond}\n"); + // Introduce a delay loop. + for (int delay = 0; delay <= 1000; delay++) + { } + + if (ctr == 10) + { + output += "Thread.Sleep called...\n"; + System.Threading.Thread.Sleep(5); + } + } + Console.WriteLine(output); + // Press "Run" to see the output. + // + } + } +} diff --git a/snippets/csharp/System/DateTime/Overview/StringFormat.cs b/snippets/csharp/System/DateTime/Overview/StringFormat.cs new file mode 100644 index 00000000000..32f0b52c8f3 --- /dev/null +++ b/snippets/csharp/System/DateTime/Overview/StringFormat.cs @@ -0,0 +1,61 @@ +using System; + +namespace SystemDateTimeReference +{ + public static class StringFormat + { + public static void Snippets() + { + ShowDefaultToString(); + ShowCultureSpecificToString(); + ShowDefaultFullDateAndTime(); + ShowCultureSpecificFullDateAndTime(); + ShowIso8601Format(); + } + + private static void ShowDefaultToString() + { + // + var date1 = new DateTime(2008, 3, 1, 7, 0, 0); + Console.WriteLine(date1.ToString()); + // For en-US culture, displays 3/1/2008 7:00:00 AM + // + } + + private static void ShowCultureSpecificToString() + { + // + var date1 = new DateTime(2008, 3, 1, 7, 0, 0); + Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR"))); + // Displays 01/03/2008 07:00:00 + // + } + + private static void ShowDefaultFullDateAndTime() + { + // + var date1 = new DateTime(2008, 3, 1, 7, 0, 0); + Console.WriteLine(date1.ToString("F")); + // Displays Saturday, March 01, 2008 7:00:00 AM + // + } + + private static void ShowCultureSpecificFullDateAndTime() + { + // + var date1 = new DateTime(2008, 3, 1, 7, 0, 0); + Console.WriteLine(date1.ToString("F", new System.Globalization.CultureInfo("fr-FR"))); + // Displays samedi 1 mars 2008 07:00:00 + // + } + + private static void ShowIso8601Format() + { + // + var date1 = new DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc); + Console.WriteLine(date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture)); + // Displays 2008-03-01T07:00:00+00:00 + // + } + } +} diff --git a/snippets/csharp/System/Delegate/CreateDelegate/Project.csproj b/snippets/csharp/System/Delegate/CreateDelegate/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Delegate/CreateDelegate/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs b/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs new file mode 100644 index 00000000000..7d5d15d287f --- /dev/null +++ b/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs @@ -0,0 +1,132 @@ +// All four permutations of instance/static with open/closed. +// +// +using System; +using System.Reflection; + +// Declare three delegate types for demonstrating the combinations +// of static versus instance methods and open versus closed +// delegates. +// +public delegate void D1(C c, string s); +public delegate void D2(string s); +public delegate void D3(); + +// A sample class with an instance method and a static method. +// +public class C +{ + private int id; + public C(int id) { this.id = id; } + + public void M1(string s) => + Console.WriteLine($"Instance method M1 on C: id = {this.id}, s = {s}"); + + public static void M2(string s) + { + Console.WriteLine($"Static method M2 on C: s = {s}"); + } +} + +public class Example2 +{ + public static void Main() + { + C c1 = new C(42); + + // Get a MethodInfo for each method. + // + MethodInfo mi1 = typeof(C).GetMethod("M1", + BindingFlags.Public | BindingFlags.Instance); + MethodInfo mi2 = typeof(C).GetMethod("M2", + BindingFlags.Public | BindingFlags.Static); + + D1 d1; + D2 d2; + D3 d3; + + Console.WriteLine("\nAn instance method closed over C."); + // In this case, the delegate and the + // method must have the same list of argument types; use + // delegate type D2 with instance method M1. + // + Delegate test = + Delegate.CreateDelegate(typeof(D2), c1, mi1, false); + + // Because false was specified for throwOnBindFailure + // in the call to CreateDelegate, the variable 'test' + // contains null if the method fails to bind (for + // example, if mi1 happened to represent a method of + // some class other than C). + // + if (test != null) + { + d2 = (D2)test; + + // The same instance of C is used every time the + // delegate is invoked. + d2("Hello, World!"); + d2("Hi, Mom!"); + } + + Console.WriteLine("\nAn open instance method."); + // In this case, the delegate has one more + // argument than the instance method; this argument comes + // at the beginning, and represents the hidden instance + // argument of the instance method. Use delegate type D1 + // with instance method M1. + // + d1 = (D1)Delegate.CreateDelegate(typeof(D1), null, mi1); + + // An instance of C must be passed in each time the + // delegate is invoked. + // + d1(c1, "Hello, World!"); + d1(new C(5280), "Hi, Mom!"); + + Console.WriteLine("\nAn open static method."); + // In this case, the delegate and the method must + // have the same list of argument types; use delegate type + // D2 with static method M2. + // + d2 = (D2)Delegate.CreateDelegate(typeof(D2), null, mi2); + + // No instances of C are involved, because this is a static + // method. + // + d2("Hello, World!"); + d2("Hi, Mom!"); + + Console.WriteLine("\nA static method closed over the first argument (String)."); + // The delegate must omit the first argument of the method. + // A string is passed as the firstArgument parameter, and + // the delegate is bound to this string. Use delegate type + // D3 with static method M2. + // + d3 = (D3)Delegate.CreateDelegate(typeof(D3), + "Hello, World!", mi2); + + // Each time the delegate is invoked, the same string is + // used. + d3(); + } +} + +/* This code example produces the following output: + +An instance method closed over C. +Instance method M1 on C: id = 42, s = Hello, World! +Instance method M1 on C: id = 42, s = Hi, Mom! + +An open instance method. +Instance method M1 on C: id = 42, s = Hello, World! +Instance method M1 on C: id = 5280, s = Hi, Mom! + +An open static method. +Static method M2 on C: s = Hello, World! +Static method M2 on C: s = Hi, Mom! + +A static method closed over the first argument (String). +Static method M2 on C: s = Hello, World! + */ +// diff --git a/snippets/csharp/System/Delegate/CreateDelegate/source.cs b/snippets/csharp/System/Delegate/CreateDelegate/source.cs new file mode 100644 index 00000000000..cd0a1acbb4e --- /dev/null +++ b/snippets/csharp/System/Delegate/CreateDelegate/source.cs @@ -0,0 +1,162 @@ +// Showing all the things D(A) can bind to. +// +// +using System; +using System.Reflection; + +// Declare a delegate type. The object of this code example +// is to show all the methods this delegate can bind to. +// +public delegate void D(C1 c); + +// Declare two sample classes, C1 and F. Class C1 has an ID +// property so instances can be identified. +// +public class C1 +{ + private int id; + public int ID => id; + public C1(int id) => this.id = id; + + public void M1(C1 c) + { + Console.WriteLine("Instance method M1(C1 c) on C1: this.id = {0}, c.ID = {1}", + this.id, c.ID); + } + + public void M2() + { + Console.WriteLine($"Instance method M2() on C1: this.id = {this.id}"); + } + + public static void M3(C1 c) + { + Console.WriteLine($"Static method M3(C1 c) on C1: c.ID = {c.ID}"); + } + + public static void M4(C1 c1, C1 c2) + { + Console.WriteLine("Static method M4(C1 c1, C1 c2) on C1: c1.ID = {0}, c2.ID = {1}", + c1.ID, c2.ID); + } +} + +public class F +{ + public void M1(C1 c) + { + Console.WriteLine($"Instance method M1(C1 c) on F: c.ID = {c.ID}"); + } + + public static void M3(C1 c) + { + Console.WriteLine($"Static method M3(C1 c) on F: c.ID = {c.ID}"); + } + + public static void M4(F f, C1 c) + { + Console.WriteLine($"Static method M4(F f, C1 c) on F: c.ID = {c.ID}"); + } +} + +public class Example +{ + public static void Main() + { + C1 c1 = new (42); + C1 c2 = new (1491); + F f1 = new (); + + D d; + + // Instance method with one argument of type C1. + MethodInfo cmi1 = typeof(C1).GetMethod("M1"); + // Instance method with no arguments. + MethodInfo cmi2 = typeof(C1).GetMethod("M2"); + // Static method with one argument of type C1. + MethodInfo cmi3 = typeof(C1).GetMethod("M3"); + // Static method with two arguments of type C1. + MethodInfo cmi4 = typeof(C1).GetMethod("M4"); + + // Instance method with one argument of type C1. + MethodInfo fmi1 = typeof(F).GetMethod("M1"); + // Static method with one argument of type C1. + MethodInfo fmi3 = typeof(F).GetMethod("M3"); + // Static method with an argument of type F and an argument + // of type C1. + MethodInfo fmi4 = typeof(F).GetMethod("M4"); + + Console.WriteLine("\nAn instance method on any type, with an argument of type C1."); + // D can represent any instance method that exactly matches its + // signature. Methods on C1 and F are shown here. + // + d = (D)Delegate.CreateDelegate(typeof(D), c1, cmi1); + d(c2); + d = (D)Delegate.CreateDelegate(typeof(D), f1, fmi1); + d(c2); + + Console.WriteLine("\nAn instance method on C1 with no arguments."); + // D can represent an instance method on C1 that has no arguments; + // in this case, the argument of D represents the hidden first + // argument of any instance method. The delegate acts like a + // static method, and an instance of C1 must be passed each time + // it is invoked. + // + d = (D)Delegate.CreateDelegate(typeof(D), null, cmi2); + d(c1); + + Console.WriteLine("\nA static method on any type, with an argument of type C1."); + // D can represent any static method with the same signature. + // Methods on F and C1 are shown here. + // + d = (D)Delegate.CreateDelegate(typeof(D), null, cmi3); + d(c1); + d = (D)Delegate.CreateDelegate(typeof(D), null, fmi3); + d(c1); + + Console.WriteLine("\nA static method on any type, with an argument of"); + Console.WriteLine(" that type and an argument of type C1."); + // D can represent any static method with one argument of the + // type the method belongs and a second argument of type C1. + // In this case, the method is closed over the instance of + // supplied for the its first argument, and acts like an instance + // method. Methods on F and C1 are shown here. + // + d = (D)Delegate.CreateDelegate(typeof(D), c1, cmi4); + d(c2); + Delegate test = + Delegate.CreateDelegate(typeof(D), f1, fmi4, false); + + // This final example specifies false for throwOnBindFailure + // in the call to CreateDelegate, so the variable 'test' + // contains Nothing if the method fails to bind (for + // example, if fmi4 happened to represent a method of + // some class other than F). + // + if (test != null) + { + d = (D)test; + d(c2); + } + } +} + +/* This code example produces the following output: + +An instance method on any type, with an argument of type C1. +Instance method M1(C1 c) on C1: this.id = 42, c.ID = 1491 +Instance method M1(C1 c) on F: c.ID = 1491 + +An instance method on C1 with no arguments. +Instance method M2() on C1: this.id = 42 + +A static method on any type, with an argument of type C1. +Static method M3(C1 c) on C1: c.ID = 42 +Static method M3(C1 c) on F: c.ID = 42 + +A static method on any type, with an argument of + that type and an argument of type C1. +Static method M4(C1 c1, C1 c2) on C1: c1.ID = 42, c2.ID = 1491 +Static method M4(F f, C1 c) on F: c.ID = 1491 +*/ +// diff --git a/snippets/csharp/System/Delegate/CreateDelegate/source1.cs b/snippets/csharp/System/Delegate/CreateDelegate/source1.cs new file mode 100644 index 00000000000..c6879c35ef5 --- /dev/null +++ b/snippets/csharp/System/Delegate/CreateDelegate/source1.cs @@ -0,0 +1,58 @@ +// +using System; +using System.Reflection; + +// Define two classes to use in the demonstration, a base class and +// a class that derives from it. +// +public class Base { } + +public class Derived : Base +{ + // Define a static method to use in the demonstration. The method + // takes an instance of Base and returns an instance of Derived. + // For the purposes of the demonstration, it is not necessary for + // the method to do anything useful. + // + public static Derived MyMethod(Base arg) + { + Base dummy = arg; + return new Derived(); + } +} + +// Define a delegate that takes an instance of Derived and returns an +// instance of Base. +// +public delegate Base Example5(Derived arg); + +class Test +{ + public static void Main() + { + // The binding flags needed to retrieve MyMethod. + BindingFlags flags = BindingFlags.Public | BindingFlags.Static; + + // Get a MethodInfo that represents MyMethod. + MethodInfo minfo = typeof(Derived).GetMethod("MyMethod", flags); + + // Demonstrate contravariance of parameter types and covariance + // of return types by using the delegate Example5 to represent + // MyMethod. The delegate binds to the method because the + // parameter of the delegate is more restrictive than the + // parameter of the method (that is, the delegate accepts an + // instance of Derived, which can always be safely passed to + // a parameter of type Base), and the return type of MyMethod + // is more restrictive than the return type of Example5 (that + // is, the method returns an instance of Derived, which can + // always be safely cast to type Base). + // + Example5 ex = + (Example5)Delegate.CreateDelegate(typeof(Example5), minfo); + + // Execute MyMethod using the delegate Example5. + // + Base b = ex(new Derived()); + } +} +// diff --git a/snippets/csharp/System/Double/CompareTo/Project.csproj b/snippets/csharp/System/Double/CompareTo/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Double/CompareTo/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Double/CompareTo/compareto2.cs b/snippets/csharp/System/Double/CompareTo/compareto2.cs new file mode 100644 index 00000000000..10a113fd4bc --- /dev/null +++ b/snippets/csharp/System/Double/CompareTo/compareto2.cs @@ -0,0 +1,18 @@ +// +using System; + +public class Example +{ + public static void Main() + { + double value1 = 6.185; + double value2 = value1 * .1 / .1; + Console.WriteLine($"Comparing {value1} and {value2}: {value1.CompareTo(value2)}{Environment.NewLine}"); + Console.WriteLine($"Comparing {value1:R} and {value2:R}: {value1.CompareTo(value2)}"); + } +} +// The example displays the following output: +// Comparing 6.185 and 6.185: -1 +// +// Comparing 6.185 and 6.1850000000000005: -1 +// diff --git a/snippets/csharp/System/Double/CompareTo/compareto3.cs b/snippets/csharp/System/Double/CompareTo/compareto3.cs new file mode 100644 index 00000000000..7ceb735d23e --- /dev/null +++ b/snippets/csharp/System/Double/CompareTo/compareto3.cs @@ -0,0 +1,18 @@ +// +using System; + +public class Example3 +{ + public static void Main() + { + double value1 = 6.185; + object value2 = value1 * .1 / .1; + Console.WriteLine($"Comparing {value1} and {value2}: {value1.CompareTo(value2)}{Environment.NewLine}"); + Console.WriteLine($"Comparing {value1:R} and {value2:R}: {value1.CompareTo(value2)}"); + } +} +// The example displays the following output: +// Comparing 6.185 and 6.185: -1 +// +// Comparing 6.185 and 6.1850000000000005: -1 +// diff --git a/snippets/csharp/System/Double/Epsilon/Project.csproj b/snippets/csharp/System/Double/Epsilon/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Double/Epsilon/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Double/Epsilon/epsilon.cs b/snippets/csharp/System/Double/Epsilon/epsilon.cs new file mode 100644 index 00000000000..4cc778bc854 --- /dev/null +++ b/snippets/csharp/System/Double/Epsilon/epsilon.cs @@ -0,0 +1,25 @@ +// +using System; + +public class Example +{ + public static void Main() + { + double[] values = { 0, Double.Epsilon, Double.Epsilon * .5 }; + + for (int ctr = 0; ctr <= values.Length - 2; ctr++) + { + for (int ctr2 = ctr + 1; ctr2 <= values.Length - 1; ctr2++) + { + Console.WriteLine($"{values[ctr]:r} = {values[ctr2]:r}: {values[ctr].Equals(values[ctr2])}"); + } + Console.WriteLine(); + } + } +} +// The example displays the following output: +// 0 = 4.94065645841247E-324: False +// 0 = 0: True +// +// 4.94065645841247E-324 = 0: False +// diff --git a/snippets/csharp/System/Double/Epsilon/epsilon1.cs b/snippets/csharp/System/Double/Epsilon/epsilon1.cs new file mode 100644 index 00000000000..20687107010 --- /dev/null +++ b/snippets/csharp/System/Double/Epsilon/epsilon1.cs @@ -0,0 +1,55 @@ +// +using System; + +public class Example1 +{ + public static void Main() + { + double[] values = { 0.0, Double.Epsilon }; + foreach (var value in values) + { + Console.WriteLine(GetComponentParts(value)); + Console.WriteLine(); + } + } + + private static string GetComponentParts(double value) + { + string result = String.Format("{0:R}: ", value); + int indent = result.Length; + + // Convert the double to an 8-byte array. + byte[] bytes = BitConverter.GetBytes(value); + // Get the sign bit (byte 7, bit 7). + result += String.Format("Sign: {0}\n", + (bytes[7] & 0x80) == 0x80 ? "1 (-)" : "0 (+)"); + + // Get the exponent (byte 6 bits 4-7 to byte 7, bits 0-6) + int exponent = (bytes[7] & 0x07F) << 4; + exponent = exponent | ((bytes[6] & 0xF0) >> 4); + int adjustment = exponent != 0 ? 1023 : 1022; + result += String.Format("{0}Exponent: 0x{1:X4} ({1})\n", new String(' ', indent), exponent - adjustment); + + // Get the significand (bits 0-51) + long significand = ((bytes[6] & 0x0F) << 48); + significand = significand | ((long)bytes[5] << 40); + significand = significand | ((long)bytes[4] << 32); + significand = significand | ((long)bytes[3] << 24); + significand = significand | ((long)bytes[2] << 16); + significand = significand | ((long)bytes[1] << 8); + significand = significand | bytes[0]; + result += String.Format("{0}Mantissa: 0x{1:X13}\n", new String(' ', indent), significand); + + return result; + } +} +// // The example displays the following output: +// 0: Sign: 0 (+) +// Exponent: 0xFFFFFC02 (-1022) +// Mantissa: 0x0000000000000 +// +// +// 4.94065645841247E-324: Sign: 0 (+) +// Exponent: 0xFFFFFC02 (-1022) +// Mantissa: 0x0000000000001 +// diff --git a/snippets/csharp/System/Double/Equals/Project.csproj b/snippets/csharp/System/Double/Equals/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Double/Equals/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Double/Equals/equalsabs1.cs b/snippets/csharp/System/Double/Equals/equalsabs1.cs new file mode 100644 index 00000000000..cb5677c7160 --- /dev/null +++ b/snippets/csharp/System/Double/Equals/equalsabs1.cs @@ -0,0 +1,50 @@ +using System; + +public class AbsExample +{ + // + public static void Main() + { + // Initialize the values. + double value1 = .1 * 10; + double value2 = 0; + for (int ctr = 0; ctr < 10; ctr++) + value2 += .1; + + Console.WriteLine($"{value1:R} = {value2:R}: " + + $"{HasMinimalDifference(value1, value2, 1)}"); + } + + public static bool HasMinimalDifference( + double value1, + double value2, + int allowableDifference + ) + { + // Convert the double values to long values. + long lValue1 = BitConverter.DoubleToInt64Bits(value1); + long lValue2 = BitConverter.DoubleToInt64Bits(value2); + + // If the signs are different, return false except for +0 and -0. + if ((lValue1 >> 63) != (lValue2 >> 63)) + { + if (value1 == value2) + return true; + + return false; + } + + // Calculate the number of possible + // floating-point values in the difference. + long diff = Math.Abs(lValue1 - lValue2); + + if (diff <= allowableDifference) + return true; + + return false; + } + // The example displays the following output: + // + // 1 = 0.99999999999999989: True + // +} diff --git a/snippets/csharp/System/Double/Equals/equalsoverl.cs b/snippets/csharp/System/Double/Equals/equalsoverl.cs index d82b6a5cc0a..8a3fad02ecd 100644 --- a/snippets/csharp/System/Double/Equals/equalsoverl.cs +++ b/snippets/csharp/System/Double/Equals/equalsoverl.cs @@ -1,7 +1,7 @@ // using System; -public class Example +public class OverExample { static double value = 112; diff --git a/snippets/csharp/System/Double/Overview/Program.cs b/snippets/csharp/System/Double/Overview/Program.cs index 170e0a43274..76ebcafc9e7 100644 --- a/snippets/csharp/System/Double/Overview/Program.cs +++ b/snippets/csharp/System/Double/Overview/Program.cs @@ -1 +1 @@ -Example9.Run(); +Example9.Run(); diff --git a/snippets/csharp/System/Double/Overview/comparison1.cs b/snippets/csharp/System/Double/Overview/comparison1.cs new file mode 100644 index 00000000000..39c0d36f900 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/comparison1.cs @@ -0,0 +1,15 @@ +// +using System; + +public class Example +{ + public static void Main() + { + double value1 = .333333333333333; + double value2 = 1.0/3; + Console.WriteLine($"{value1} = {value2}: {value1.Equals(value2)}"); + } +} +// The example displays the following output: +// 0.333333333333333 = 0.33333333333333331: False +// diff --git a/snippets/csharp/System/Double/Overview/comparison3.cs b/snippets/csharp/System/Double/Overview/comparison3.cs new file mode 100644 index 00000000000..2c548a3ae98 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/comparison3.cs @@ -0,0 +1,19 @@ +using System; + +public class Example2 +{ + public static void Main() + { + // + double value1 = .333333333333333; + double value2 = 1.0 / 3; + int precision = 7; + value1 = Math.Round(value1, precision); + value2 = Math.Round(value2, precision); + Console.WriteLine($"{value1} = {value2}: {value1.Equals(value2)}"); + + // The example displays the following output: + // 0.3333333 = 0.3333333: True + // + } +} diff --git a/snippets/csharp/System/Double/Overview/comparison4.cs b/snippets/csharp/System/Double/Overview/comparison4.cs new file mode 100644 index 00000000000..577ba93083f --- /dev/null +++ b/snippets/csharp/System/Double/Overview/comparison4.cs @@ -0,0 +1,41 @@ +// +using System; + +public class Example3 +{ + public static void Main() + { + double one1 = .1 * 10; + double one2 = 0; + for (int ctr = 1; ctr <= 10; ctr++) + one2 += .1; + + Console.WriteLine($"{one1} = {one2}: {one1.Equals(one2)}"); + Console.WriteLine($"{one1} is approximately equal to {one2}: {IsApproximatelyEqual(one1, one2, .000000001)}"); + } + + static bool IsApproximatelyEqual(double value1, double value2, double epsilon) + { + // If they are equal anyway, just return True. + if (value1.Equals(value2)) + return true; + + // Handle NaN, Infinity. + if (Double.IsInfinity(value1) | Double.IsNaN(value1)) + return value1.Equals(value2); + else if (Double.IsInfinity(value2) | Double.IsNaN(value2)) + return value1.Equals(value2); + + // Handle zero to avoid division by zero + double divisor = Math.Max(value1, value2); + if (divisor.Equals(0)) + divisor = Math.Min(value1, value2); + + return Math.Abs((value1 - value2) / divisor) <= epsilon; + } +} + +// The example displays the following output: +// 1 = 0.99999999999999989: False +// 1 is approximately equal to 0.99999999999999989: True +// diff --git a/snippets/csharp/System/Double/Overview/convert1.cs b/snippets/csharp/System/Double/Overview/convert1.cs new file mode 100644 index 00000000000..dee3e3e473f --- /dev/null +++ b/snippets/csharp/System/Double/Overview/convert1.cs @@ -0,0 +1,49 @@ +using System; + +public class Example4 +{ + public static void Main() + { + // + dynamic[] values = { Byte.MinValue, Byte.MaxValue, Decimal.MinValue, + Decimal.MaxValue, Int16.MinValue, Int16.MaxValue, + Int32.MinValue, Int32.MaxValue, Int64.MinValue, + Int64.MaxValue, SByte.MinValue, SByte.MaxValue, + Single.MinValue, Single.MaxValue, UInt16.MinValue, + UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue, + UInt64.MinValue, UInt64.MaxValue }; + double dblValue; + foreach (dynamic value in values) + { + if (value.GetType() == typeof(decimal)) + dblValue = (double)value; + else + dblValue = value; + Console.WriteLine($"{value} ({value.GetType().Name}) --> " + + $"{dblValue:R} ({dblValue.GetType().Name})"); + } + + // The example displays the following output: + // 0 (Byte) --> 0 (Double) + // 255 (Byte) --> 255 (Double) + // -79228162514264337593543950335 (Decimal) --> -7.9228162514264338E+28 (Double) + // 79228162514264337593543950335 (Decimal) --> 7.9228162514264338E+28 (Double) + // -32768 (Int16) --> -32768 (Double) + // 32767 (Int16) --> 32767 (Double) + // -2147483648 (Int32) --> -2147483648 (Double) + // 2147483647 (Int32) --> 2147483647 (Double) + // -9223372036854775808 (Int64) --> -9.2233720368547758E+18 (Double) + // 9223372036854775807 (Int64) --> 9.2233720368547758E+18 (Double) + // -128 (SByte) --> -128 (Double) + // 127 (SByte) --> 127 (Double) + // -3.402823E+38 (Single) --> -3.4028234663852886E+38 (Double) + // 3.402823E+38 (Single) --> 3.4028234663852886E+38 (Double) + // 0 (UInt16) --> 0 (Double) + // 65535 (UInt16) --> 65535 (Double) + // 0 (UInt32) --> 0 (Double) + // 4294967295 (UInt32) --> 4294967295 (Double) + // 0 (UInt64) --> 0 (Double) + // 18446744073709551615 (UInt64) --> 1.8446744073709552E+19 (Double) + // + } +} diff --git a/snippets/csharp/System/Double/Overview/convert2.cs b/snippets/csharp/System/Double/Overview/convert2.cs new file mode 100644 index 00000000000..efd4c149833 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/convert2.cs @@ -0,0 +1,149 @@ +// +using System; + +public class Example5 +{ + public static void Main() + { + Double[] values = { Double.MinValue, -67890.1234, -12345.6789, + 12345.6789, 67890.1234, Double.MaxValue, + Double.NaN, Double.PositiveInfinity, + Double.NegativeInfinity }; + checked + { + foreach (var value in values) + { + try + { + Int64 lValue = (long)value; + Console.WriteLine($"{value} ({value.GetType().Name}) --> {lValue} (0x{lValue:X16}) ({lValue.GetType().Name})"); + } + catch (OverflowException) + { + Console.WriteLine($"Unable to convert {value} to Int64."); + } + try + { + UInt64 ulValue = (ulong)value; + Console.WriteLine($"{value} ({value.GetType().Name}) --> {ulValue} (0x{ulValue:X16}) ({ulValue.GetType().Name})"); + } + catch (OverflowException) + { + Console.WriteLine($"Unable to convert {value} to UInt64."); + } + try + { + Decimal dValue = (decimal)value; + Console.WriteLine($"{value} ({value.GetType().Name}) --> {dValue} ({dValue.GetType().Name})"); + } + catch (OverflowException) + { + Console.WriteLine($"Unable to convert {value} to Decimal."); + } + try + { + Single sValue = (float)value; + Console.WriteLine($"{value} ({value.GetType().Name}) --> {sValue} ({sValue.GetType().Name})"); + } + catch (OverflowException) + { + Console.WriteLine($"Unable to convert {value} to Single."); + } + Console.WriteLine(); + } + } + } +} +// The example displays the following output for conversions performed +// in a checked context: +// Unable to convert -1.79769313486232E+308 to Int64. +// Unable to convert -1.79769313486232E+308 to UInt64. +// Unable to convert -1.79769313486232E+308 to Decimal. +// -1.79769313486232E+308 (Double) --> -Infinity (Single) +// +// -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64) +// Unable to convert -67890.1234 to UInt64. +// -67890.1234 (Double) --> -67890.1234 (Decimal) +// -67890.1234 (Double) --> -67890.13 (Single) +// +// -12345.6789 (Double) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64) +// Unable to convert -12345.6789 to UInt64. +// -12345.6789 (Double) --> -12345.6789 (Decimal) +// -12345.6789 (Double) --> -12345.68 (Single) +// +// 12345.6789 (Double) --> 12345 (0x0000000000003039) (Int64) +// 12345.6789 (Double) --> 12345 (0x0000000000003039) (UInt64) +// 12345.6789 (Double) --> 12345.6789 (Decimal) +// 12345.6789 (Double) --> 12345.68 (Single) +// +// 67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64) +// 67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64) +// 67890.1234 (Double) --> 67890.1234 (Decimal) +// 67890.1234 (Double) --> 67890.13 (Single) +// +// Unable to convert 1.79769313486232E+308 to Int64. +// Unable to convert 1.79769313486232E+308 to UInt64. +// Unable to convert 1.79769313486232E+308 to Decimal. +// 1.79769313486232E+308 (Double) --> Infinity (Single) +// +// Unable to convert NaN to Int64. +// Unable to convert NaN to UInt64. +// Unable to convert NaN to Decimal. +// NaN (Double) --> NaN (Single) +// +// Unable to convert Infinity to Int64. +// Unable to convert Infinity to UInt64. +// Unable to convert Infinity to Decimal. +// Infinity (Double) --> Infinity (Single) +// +// Unable to convert -Infinity to Int64. +// Unable to convert -Infinity to UInt64. +// Unable to convert -Infinity to Decimal. +// -Infinity (Double) --> -Infinity (Single) +// The example displays the following output for conversions performed +// in an unchecked context: +// -1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +// -1.79769313486232E+308 (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64) +// Unable to convert -1.79769313486232E+308 to Decimal. +// -1.79769313486232E+308 (Double) --> -Infinity (Single) +// +// -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64) +// -67890.1234 (Double) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64) +// -67890.1234 (Double) --> -67890.1234 (Decimal) +// -67890.1234 (Double) --> -67890.13 (Single) +// +// -12345.6789 (Double) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64) +// -12345.6789 (Double) --> 18446744073709539271 (0xFFFFFFFFFFFFCFC7) (UInt64) +// -12345.6789 (Double) --> -12345.6789 (Decimal) +// -12345.6789 (Double) --> -12345.68 (Single) +// +// 12345.6789 (Double) --> 12345 (0x0000000000003039) (Int64) +// 12345.6789 (Double) --> 12345 (0x0000000000003039) (UInt64) +// 12345.6789 (Double) --> 12345.6789 (Decimal) +// 12345.6789 (Double) --> 12345.68 (Single) +// +// 67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64) +// 67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64) +// 67890.1234 (Double) --> 67890.1234 (Decimal) +// 67890.1234 (Double) --> 67890.13 (Single) +// +// 1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +// 1.79769313486232E+308 (Double) --> 0 (0x0000000000000000) (UInt64) +// Unable to convert 1.79769313486232E+308 to Decimal. +// 1.79769313486232E+308 (Double) --> Infinity (Single) +// +// NaN (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +// NaN (Double) --> 0 (0x0000000000000000) (UInt64) +// Unable to convert NaN to Decimal. +// NaN (Double) --> NaN (Single) +// +// Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +// Infinity (Double) --> 0 (0x0000000000000000) (UInt64) +// Unable to convert Infinity to Decimal. +// Infinity (Double) --> Infinity (Single) +// +// -Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +// -Infinity (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64) +// Unable to convert -Infinity to Decimal. +// -Infinity (Double) --> -Infinity (Single) +// diff --git a/snippets/csharp/System/Double/Overview/exceptional1.cs b/snippets/csharp/System/Double/Overview/exceptional1.cs new file mode 100644 index 00000000000..73330fc6ca4 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/exceptional1.cs @@ -0,0 +1,18 @@ +// +using System; + +public class Example6 +{ + public static void Main() + { + Double value1 = 1.1632875981534209e-225; + Double value2 = 9.1642346778e-175; + Double result = value1 * value2; + Console.WriteLine($"{value1} * {value2} = {result}"); + Console.WriteLine($"{result} = 0: {result.Equals(0.0)}"); + } +} +// The example displays the following output: +// 1.16328759815342E-225 * 9.1642346778E-175 = 0 +// 0 = 0: True +// diff --git a/snippets/csharp/System/Double/Overview/exceptional2.cs b/snippets/csharp/System/Double/Overview/exceptional2.cs new file mode 100644 index 00000000000..68e1e4b4cb5 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/exceptional2.cs @@ -0,0 +1,27 @@ +// +using System; + +public class Example7 +{ + public static void Main() + { + Double value1 = 4.565e153; + Double value2 = 6.9375e172; + Double result = value1 * value2; + Console.WriteLine($"PositiveInfinity: {Double.IsPositiveInfinity(result)}"); + Console.WriteLine($"NegativeInfinity: {Double.IsNegativeInfinity(result)}{Environment.NewLine}"); + + value1 = -value1; + result = value1 * value2; + Console.WriteLine($"PositiveInfinity: {Double.IsPositiveInfinity(result)}"); + Console.WriteLine($"NegativeInfinity: {Double.IsNegativeInfinity(result)}"); + } +} + +// The example displays the following output: +// PositiveInfinity: True +// NegativeInfinity: False +// +// PositiveInfinity: False +// NegativeInfinity: True +// diff --git a/snippets/csharp/System/Double/Overview/precision1.cs b/snippets/csharp/System/Double/Overview/precision1.cs new file mode 100644 index 00000000000..ff8c2abd667 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/precision1.cs @@ -0,0 +1,24 @@ +using System; + +public class Example8 +{ + public static void Run() + { + // + double value = -4.42330604244772E-305; + + double fromLiteral = -4.42330604244772E-305; + double fromVariable = value; + double fromParse = double.Parse("-4.42330604244772E-305"); + + Console.WriteLine("Double value from literal: {0,29:R}", fromLiteral); + Console.WriteLine("Double value from variable: {0,28:R}", fromVariable); + Console.WriteLine("Double value from Parse method: {0,24:R}", fromParse); + + // The output is: + // Double value from literal: -4.42330604244772E-305 + // Double value from variable: -4.42330604244772E-305 + // Double value from Parse method: -4.42330604244772E-305 + // + } +} diff --git a/snippets/csharp/System/Double/Overview/precisionlist1.cs b/snippets/csharp/System/Double/Overview/precisionlist1.cs index ce19a1e9735..721c202fa92 100644 --- a/snippets/csharp/System/Double/Overview/precisionlist1.cs +++ b/snippets/csharp/System/Double/Overview/precisionlist1.cs @@ -1,4 +1,4 @@ -// +// using System; public class Example9 diff --git a/snippets/csharp/System/Double/Overview/precisionlist3.cs b/snippets/csharp/System/Double/Overview/precisionlist3.cs new file mode 100644 index 00000000000..11e92c87224 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/precisionlist3.cs @@ -0,0 +1,26 @@ +// +using System; + +public class Example10 +{ + public static void Main() + { + Double[] values = { 10.0, 2.88, 2.88, 2.88, 9.0 }; + Double result = 27.64; + Double total = 0; + foreach (var value in values) + total += value; + + if (total.Equals(result)) + Console.WriteLine("The sum of the values equals the total."); + else + Console.WriteLine($"The sum of the values ({total}) does not equal the total ({result})."); + } +} +// The example displays the following output: +// The sum of the values (36.64) does not equal the total (36.64). +// +// If the index items in the Console.WriteLine statement are changed to {0:R}, +// the example displays the following output: +// The sum of the values (27.639999999999997) does not equal the total (27.64). +// diff --git a/snippets/csharp/System/Double/Overview/representation1.cs b/snippets/csharp/System/Double/Overview/representation1.cs new file mode 100644 index 00000000000..52b1d272ab1 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/representation1.cs @@ -0,0 +1,21 @@ +// +using System; + +public class Example13 +{ + public static void Main() + { + Double value = .1; + Double result1 = value * 10; + Double result2 = 0; + for (int ctr = 1; ctr <= 10; ctr++) + result2 += value; + + Console.WriteLine($".1 * 10: {result1:R}"); + Console.WriteLine($".1 Added 10 times: {result2:R}"); + } +} +// The example displays the following output: +// .1 * 10: 1 +// .1 Added 10 times: 0.99999999999999989 +// diff --git a/snippets/csharp/System/Double/Overview/representation2.cs b/snippets/csharp/System/Double/Overview/representation2.cs new file mode 100644 index 00000000000..d4ab7b394b6 --- /dev/null +++ b/snippets/csharp/System/Double/Overview/representation2.cs @@ -0,0 +1,15 @@ +// +using System; + +public class Example14 +{ + public static void Main() + { + Double value = 123456789012.34567; + Double additional = Double.Epsilon * 1e15; + Console.WriteLine($"{value} + {additional} = {value + additional}"); + } +} +// The example displays the following output: +// 123456789012.346 + 4.94065645841247E-309 = 123456789012.346 +// diff --git a/snippets/csharp/System/Enum/Overview/EnumMain.cs b/snippets/csharp/System/Enum/Overview/EnumMain.cs new file mode 100644 index 00000000000..11ea8acf442 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/EnumMain.cs @@ -0,0 +1,32 @@ +// +using System; + +public class EnumTest { + enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday }; + enum BoilingPoints { Celsius = 100, Fahrenheit = 212 }; + [Flags] + enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 }; + + public static void Main() { + + Type weekdays = typeof(Days); + Type boiling = typeof(BoilingPoints); + + Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:"); + + foreach ( string s in Enum.GetNames(weekdays) ) + Console.WriteLine( "{0,-11}= {1}", s, Enum.Format( weekdays, Enum.Parse(weekdays, s), "d")); + + Console.WriteLine(); + Console.WriteLine("Enums can also be created which have values that represent some meaningful amount."); + Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:"); + + foreach ( string s in Enum.GetNames(boiling) ) + Console.WriteLine( "{0,-11}= {1}", s, Enum.Format(boiling, Enum.Parse(boiling, s), "d")); + + Colors myColors = Colors.Red | Colors.Blue | Colors.Yellow; + Console.WriteLine(); + Console.WriteLine($"myColors holds a combination of colors. Namely: {myColors}"); + } +} +// diff --git a/snippets/csharp/System/Enum/Overview/Extensions.cs b/snippets/csharp/System/Enum/Overview/Extensions.cs new file mode 100644 index 00000000000..b5a109fb659 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/Extensions.cs @@ -0,0 +1,41 @@ +// +using System; + +// Define an enumeration to represent student grades. +public enum Grades { F = 0, D = 1, C = 2, B = 3, A = 4 }; + +// Define an extension method for the Grades enumeration. +public static class Extensions +{ + public static Grades minPassing = Grades.D; + + public static bool Passing(this Grades grade) + { + return grade >= minPassing; + } +} + +class Example8 +{ + static void Main() + { + Grades g1 = Grades.D; + Grades g2 = Grades.F; + Console.WriteLine($"{g1} {(g1.Passing() ? "is" : "is not")} a passing grade."); + Console.WriteLine($"{g2} {(g2.Passing() ? "is" : "is not")} a passing grade."); + + Extensions.minPassing = Grades.C; + Console.WriteLine("\nRaising the bar!\n"); + Console.WriteLine($"{g1} {(g1.Passing() ? "is" : "is not")} a passing grade."); + Console.WriteLine($"{g2} {(g2.Passing() ? "is" : "is not")} a passing grade."); + } +} +// The example displays the following output: +// D is a passing grade. +// F is not a passing grade. +// +// Raising the bar! +// +// D is not a passing grade. +// F is not a passing grade. +// diff --git a/snippets/csharp/System/Enum/Overview/Project.csproj b/snippets/csharp/System/Enum/Overview/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Enum/Overview/class1.cs b/snippets/csharp/System/Enum/Overview/class1.cs new file mode 100644 index 00000000000..d0dc14f9387 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/class1.cs @@ -0,0 +1,18 @@ +using System; + +// +public enum ArrivalStatus { Unknown=-3, Late=-1, OnTime=0, Early=1 }; +// + +// +public class Example +{ + public static void Main() + { + ArrivalStatus status = ArrivalStatus.OnTime; + Console.WriteLine($"Arrival Status: {status} ({status:D})"); + } +} +// The example displays the following output: +// Arrival Status: OnTime (0) +// diff --git a/snippets/csharp/System/Enum/Overview/class2.cs b/snippets/csharp/System/Enum/Overview/class2.cs new file mode 100644 index 00000000000..0e3d0d01c4c --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/class2.cs @@ -0,0 +1,33 @@ +using System; + +public class Example1 +{ + public static void Main() + { + // + ArrivalStatus status1 = new ArrivalStatus(); + Console.WriteLine($"Arrival Status: {status1} ({status1:D})"); + // The example displays the following output: + // Arrival Status: OnTime (0) + // + + // + ArrivalStatus status2 = (ArrivalStatus)1; + Console.WriteLine($"Arrival Status: {status2} ({status2:D})"); + // The example displays the following output: + // Arrival Status: Early (1) + // + + // + int value3 = 2; + ArrivalStatus status3 = (ArrivalStatus)value3; + + int value4 = (int)status3; + // + + // + int number = -1; + ArrivalStatus arrived = (ArrivalStatus)ArrivalStatus.ToObject(typeof(ArrivalStatus), number); + // + } +} diff --git a/snippets/csharp/System/Enum/Overview/classbitwise1.cs b/snippets/csharp/System/Enum/Overview/classbitwise1.cs new file mode 100644 index 00000000000..ed2365a2484 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/classbitwise1.cs @@ -0,0 +1,63 @@ +using System; + +// +[Flags] +public enum Pets +{ + None = 0, Dog = 1, Cat = 2, Bird = 4, Rodent = 8, + Reptile = 16, Other = 32 +}; + +// + +public class Example2 +{ + public static void Main() + { + // + Pets familyPets = Pets.Dog | Pets.Cat; + Console.WriteLine($"Pets: {familyPets:G} ({familyPets:D})"); + // The example displays the following output: + // Pets: Dog, Cat (3) + // + + ShowHasFlag(); + ShowIfSet(); + TestForNone(); + } + + private static void ShowHasFlag() + { + // + Pets familyPets = Pets.Dog | Pets.Cat; + if (familyPets.HasFlag(Pets.Dog)) + Console.WriteLine("The family has a dog."); + // The example displays the following output: + // The family has a dog. + // + } + + private static void ShowIfSet() + { + // + Pets familyPets = Pets.Dog | Pets.Cat; + if ((familyPets & Pets.Dog) == Pets.Dog) + Console.WriteLine("The family has a dog."); + // The example displays the following output: + // The family has a dog. + // + } + + private static void TestForNone() + { + // + Pets familyPets = Pets.Dog | Pets.Cat; + if (familyPets == Pets.None) + Console.WriteLine("The family has no pets."); + else + Console.WriteLine("The family has pets."); + // The example displays the following output: + // The family has pets. + // + } +} diff --git a/snippets/csharp/System/Enum/Overview/classconversion1.cs b/snippets/csharp/System/Enum/Overview/classconversion1.cs new file mode 100644 index 00000000000..0165fd21373 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/classconversion1.cs @@ -0,0 +1,27 @@ +// +using System; + +public class Example3 +{ + public static void Main() + { + int[] values = { -3, -1, 0, 1, 5, Int32.MaxValue }; + foreach (var value in values) + { + ArrivalStatus status; + if (Enum.IsDefined(typeof(ArrivalStatus), value)) + status = (ArrivalStatus)value; + else + status = ArrivalStatus.Unknown; + Console.WriteLine($"Converted {value:N0} to {status}"); + } + } +} +// The example displays the following output: +// Converted -3 to Unknown +// Converted -1 to Late +// Converted 0 to OnTime +// Converted 1 to Early +// Converted 5 to Unknown +// Converted 2,147,483,647 to Unknown +// diff --git a/snippets/csharp/System/Enum/Overview/classconversion2.cs b/snippets/csharp/System/Enum/Overview/classconversion2.cs new file mode 100644 index 00000000000..0ecfe35cc36 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/classconversion2.cs @@ -0,0 +1,15 @@ +using System; + +public class Example4 +{ + public static void Main() + { + // + ArrivalStatus status = ArrivalStatus.Early; + var number = Convert.ChangeType(status, Enum.GetUnderlyingType(typeof(ArrivalStatus))); + Console.WriteLine($"Converted {status} to {number}"); + // The example displays the following output: + // Converted Early to 1 + // + } +} diff --git a/snippets/csharp/System/Enum/Overview/classformat1.cs b/snippets/csharp/System/Enum/Overview/classformat1.cs new file mode 100644 index 00000000000..b621d0f931d --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/classformat1.cs @@ -0,0 +1,20 @@ +using System; + +public class Example5 +{ + public static void Main() + { + // + string[] formats = { "G", "F", "D", "X" }; + ArrivalStatus status = ArrivalStatus.Late; + foreach (var fmt in formats) + Console.WriteLine(status.ToString(fmt)); + + // The example displays the following output: + // Late + // Late + // -1 + // FFFFFFFF + // + } +} diff --git a/snippets/csharp/System/Enum/Overview/classiterate.cs b/snippets/csharp/System/Enum/Overview/classiterate.cs new file mode 100644 index 00000000000..f9c3667b299 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/classiterate.cs @@ -0,0 +1,49 @@ +using System; + +public class Example6 +{ + public static void Main() + { + GetEnumByName(); + Console.WriteLine("-----"); + GetEnumByValue(); + } + + private static void GetEnumByName() + { + // + string[] names = Enum.GetNames(typeof(ArrivalStatus)); + Console.WriteLine($"Members of {typeof(ArrivalStatus).Name}:"); + Array.Sort(names); + foreach (var name in names) + { + ArrivalStatus status = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), name); + Console.WriteLine($" {status} ({status:D})"); + } + // The example displays the following output: + // Members of ArrivalStatus: + // Early (1) + // Late (-1) + // OnTime (0) + // Unknown (-3) + // + } + + private static void GetEnumByValue() + { + // + var values = Enum.GetValues(typeof(ArrivalStatus)); + Console.WriteLine($"Members of {typeof(ArrivalStatus).Name}:"); + foreach (ArrivalStatus status in values) + { + Console.WriteLine($" {status} ({status:D})"); + } + // The example displays the following output: + // Members of ArrivalStatus: + // OnTime (0) + // Early (1) + // Unknown (-3) + // Late (-1) + // + } +} diff --git a/snippets/csharp/System/Enum/Overview/classparse1.cs b/snippets/csharp/System/Enum/Overview/classparse1.cs new file mode 100644 index 00000000000..4f7f447f747 --- /dev/null +++ b/snippets/csharp/System/Enum/Overview/classparse1.cs @@ -0,0 +1,39 @@ +using System; + +public class Example7 +{ + public static void Main() + { + // + string number = "-1"; + string name = "Early"; + + try + { + ArrivalStatus status1 = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), number); + if (!(Enum.IsDefined(typeof(ArrivalStatus), status1))) + status1 = ArrivalStatus.Unknown; + Console.WriteLine($"Converted '{number}' to {status1}"); + } + catch (FormatException) + { + Console.WriteLine($"Unable to convert '{number}' to an ArrivalStatus value."); + } + + ArrivalStatus status2; + if (Enum.TryParse(name, out status2)) + { + if (!(Enum.IsDefined(typeof(ArrivalStatus), status2))) + status2 = ArrivalStatus.Unknown; + Console.WriteLine($"Converted '{name}' to {status2}"); + } + else + { + Console.WriteLine($"Unable to convert '{number}' to an ArrivalStatus value."); + } + // The example displays the following output: + // Converted '-1' to Late + // Converted 'Early' to Early + // + } +} diff --git a/snippets/csharp/System/FormatException/Overview/example1.cs b/snippets/csharp/System/FormatException/Overview/example1.cs index 012f637e6f8..d13d240d3d9 100644 --- a/snippets/csharp/System/FormatException/Overview/example1.cs +++ b/snippets/csharp/System/FormatException/Overview/example1.cs @@ -1,12 +1,12 @@ // using System; -public class Example +public class Example1 { public enum TemperatureScale { Celsius, Fahrenheit, Kelvin } - public static void Main() + public static void Run() { String info = GetCurrentTemperature(); Console.WriteLine(info); @@ -24,6 +24,7 @@ private static String GetCurrentTemperature() return result; } } + // The example displays output like the following: // Unhandled Exception: System.FormatException: Format specifier was invalid. // at System.Number.FormatDecimal(Decimal value, String format, NumberFormatInfo info) diff --git a/snippets/csharp/System/FormatException/Overview/format4.cs b/snippets/csharp/System/FormatException/Overview/format4.cs index 772c9b37849..060eb9c8245 100644 --- a/snippets/csharp/System/FormatException/Overview/format4.cs +++ b/snippets/csharp/System/FormatException/Overview/format4.cs @@ -5,12 +5,12 @@ public class FormatExample4 public static void Run() { // - string formatString = " {0,10} ({0,8:X8})\n" + - "And {1,10} ({1,8:X8})\n" + + string formatString = " {0,10} ({0,8:X8})\n" + + "And {1,10} ({1,8:X8})\n" + " = {2,10} ({2,8:X8})"; int value1 = 16932; int value2 = 15421; - string result = string.Format(formatString, + string result = string.Format(formatString, value1, value2, value1 & value2); Console.WriteLine(result); diff --git a/snippets/csharp/System/FormatException/Overview/format5.cs b/snippets/csharp/System/FormatException/Overview/format5.cs index 4d4adce3647..91199101f5d 100644 --- a/snippets/csharp/System/FormatException/Overview/format5.cs +++ b/snippets/csharp/System/FormatException/Overview/format5.cs @@ -7,16 +7,16 @@ public static void Main() // DateTime date1 = new DateTime(2009, 7, 1); TimeSpan hiTime = new TimeSpan(14, 17, 32); - decimal hiTemp = 62.1m; + decimal hiTemp = 62.1m; TimeSpan loTime = new TimeSpan(3, 16, 10); - decimal loTemp = 54.8m; + decimal loTemp = 54.8m; - string result1 = String.Format("Temperature on {0:d}:\n{1,11}: {2} degrees (hi)\n{3,11}: {4} degrees (lo)", + string result1 = String.Format("Temperature on {0:d}:\n{1,11}: {2} degrees (hi)\n{3,11}: {4} degrees (lo)", date1, hiTime, hiTemp, loTime, loTemp); Console.WriteLine(result1); Console.WriteLine(); - - string result2 = String.Format("Temperature on {0:d}:\n{1,11}: {2} degrees (hi)\n{3,11}: {4} degrees (lo)", + + string result2 = String.Format("Temperature on {0:d}:\n{1,11}: {2} degrees (hi)\n{3,11}: {4} degrees (lo)", new object[] { date1, hiTime, hiTemp, loTime, loTemp }); Console.WriteLine(result2); // The example displays output like the following: diff --git a/snippets/csharp/System/FormatException/Overview/format7.cs b/snippets/csharp/System/FormatException/Overview/format7.cs index 43b1c2139dd..df97a185d5e 100644 --- a/snippets/csharp/System/FormatException/Overview/format7.cs +++ b/snippets/csharp/System/FormatException/Overview/format7.cs @@ -6,10 +6,10 @@ public static void Main() { // DateTime birthdate = new DateTime(1993, 7, 28); - DateTime[] dates = { new DateTime(1993, 8, 16), - new DateTime(1994, 7, 28), - new DateTime(2000, 10, 16), - new DateTime(2003, 7, 27), + DateTime[] dates = { new DateTime(1993, 8, 16), + new DateTime(1994, 7, 28), + new DateTime(2000, 10, 16), + new DateTime(2003, 7, 27), new DateTime(2007, 5, 27) }; foreach (DateTime dateValue in dates) @@ -22,11 +22,11 @@ public static void Main() if (birthdate.AddYears(years) <= dateValue) { output = String.Format("You are now {0} years old.", years); Console.WriteLine(output); - } + } else { output = String.Format("You are now {0} years old.", years - 1); Console.WriteLine(output); - } + } } // The example displays the following output: // You are now 0 years old. diff --git a/snippets/csharp/System/FormatException/Overview/formatexample4.cs b/snippets/csharp/System/FormatException/Overview/formatexample4.cs index 6da03ced2be..ba26ed95182 100644 --- a/snippets/csharp/System/FormatException/Overview/formatexample4.cs +++ b/snippets/csharp/System/FormatException/Overview/formatexample4.cs @@ -6,21 +6,21 @@ public class FormatExample6 public static void Main() { // - Dictionary temperatureInfo = new Dictionary(); + Dictionary temperatureInfo = new Dictionary(); temperatureInfo.Add(new DateTime(2010, 6, 1, 14, 0, 0), 87.46); temperatureInfo.Add(new DateTime(2010, 12, 1, 10, 0, 0), 36.81); - + Console.WriteLine("Temperature Information:\n"); - string output; + string output; foreach (var item in temperatureInfo) { - output = String.Format("Temperature at {0,8:t} on {0,9:d}: {1,5:N1}°F", + output = String.Format("Temperature at {0,8:t} on {0,9:d}: {1,5:N1}°F", item.Key, item.Value); Console.WriteLine(output); } // The example displays output like the following: // Temperature Information: - // + // // Temperature at 2:00 PM on 6/1/2010: 87.5°F // Temperature at 10:00 AM on 12/1/2010: 36.8°F // diff --git a/snippets/csharp/System/FormatException/Overview/formatoverload1.cs b/snippets/csharp/System/FormatException/Overview/formatoverload1.cs index 067922e00d7..183e301afce 100644 --- a/snippets/csharp/System/FormatException/Overview/formatoverload1.cs +++ b/snippets/csharp/System/FormatException/Overview/formatoverload1.cs @@ -5,14 +5,14 @@ public class Example2 public static void Main() { // - DateTime dat = new DateTime(2012, 1, 17, 9, 30, 0); + DateTime dat = new DateTime(2012, 1, 17, 9, 30, 0); string city = "Chicago"; int temp = -16; string output = String.Format("At {0} in {1}, the temperature was {2} degrees.", dat, city, temp); Console.WriteLine(output); // The example displays output like the following: - // At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees. + // At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees. // } } diff --git a/snippets/csharp/System/FormatException/Overview/formatoverload2.cs b/snippets/csharp/System/FormatException/Overview/formatoverload2.cs index 9e9e5396bd6..c0f3356cbb2 100644 --- a/snippets/csharp/System/FormatException/Overview/formatoverload2.cs +++ b/snippets/csharp/System/FormatException/Overview/formatoverload2.cs @@ -6,14 +6,14 @@ public static void Main() { // // Create array of 5-tuples with population data for three U.S. cities, 1940-1950. - Tuple[] cities = - { Tuple.Create("Los Angeles", new DateTime(1940, 1, 1), 1504277, + Tuple[] cities = + { Tuple.Create("Los Angeles", new DateTime(1940, 1, 1), 1504277, new DateTime(1950, 1, 1), 1970358), - Tuple.Create("New York", new DateTime(1940, 1, 1), 7454995, - new DateTime(1950, 1, 1), 7891957), - Tuple.Create("Chicago", new DateTime(1940, 1, 1), 3396808, - new DateTime(1950, 1, 1), 3620962), - Tuple.Create("Detroit", new DateTime(1940, 1, 1), 1623452, + Tuple.Create("New York", new DateTime(1940, 1, 1), 7454995, + new DateTime(1950, 1, 1), 7891957), + Tuple.Create("Chicago", new DateTime(1940, 1, 1), 3396808, + new DateTime(1950, 1, 1), 3620962), + Tuple.Create("Detroit", new DateTime(1940, 1, 1), 1623452, new DateTime(1950, 1, 1), 1849568) }; // Display header @@ -28,7 +28,7 @@ public static void Main() } // The example displays the following output: // City Year Population Year Population Change (%) - // + // // Los Angeles 1940 1,504,277 1950 1,970,358 31.0 % // New York 1940 7,454,995 1950 7,891,957 5.9 % // Chicago 1940 3,396,808 1950 3,620,962 6.6 % diff --git a/snippets/csharp/System/FormatException/Overview/iformattable4.cs b/snippets/csharp/System/FormatException/Overview/iformattable4.cs index 9169bb84335..65557e4447e 100644 --- a/snippets/csharp/System/FormatException/Overview/iformattable4.cs +++ b/snippets/csharp/System/FormatException/Overview/iformattable4.cs @@ -9,6 +9,7 @@ public static void Main() Console.WriteLine(Guid.Parse(guidString)); } } + // The example displays the following output: // ba748d5c-ae5f-4cca-84e5-1ac5291c38cb // diff --git a/snippets/csharp/System/FormatException/Overview/interceptor2.cs b/snippets/csharp/System/FormatException/Overview/interceptor2.cs index 010a3529f85..3f952db5b4b 100644 --- a/snippets/csharp/System/FormatException/Overview/interceptor2.cs +++ b/snippets/csharp/System/FormatException/Overview/interceptor2.cs @@ -11,16 +11,16 @@ public object GetFormat(Type formatType) else return null; } - - public string Format(String format, Object obj, IFormatProvider provider) + + public string Format(String format, Object obj, IFormatProvider provider) { // Display information about method call. string formatString = format ?? ""; Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}", provider.GetType().Name, obj ?? "", formatString); - + if (obj == null) return String.Empty; - + // If this is a byte and the "R" format string, format it with Roman numerals. if (obj is Byte && formatString.ToUpper().Equals("R")) { Byte value = (Byte) obj; @@ -30,7 +30,7 @@ public string Format(String format, Object obj, IFormatProvider provider) // Get the hundreds digit(s) result = Math.DivRem(value, 100, out remainder); - if (result > 0) + if (result > 0) returnString = new String('C', result); value = (Byte) remainder; // Get the 50s digit @@ -42,24 +42,24 @@ public string Format(String format, Object obj, IFormatProvider provider) result = Math.DivRem(value, 10, out remainder); if (result > 0) returnString += new String('X', result); - value = (Byte) remainder; + value = (Byte) remainder; // Get the fives digit. result = Math.DivRem(value, 5, out remainder); if (result > 0) returnString += "V"; value = (Byte) remainder; // Add the ones digit. - if (remainder > 0) + if (remainder > 0) returnString += new String('I', remainder); - + // Check whether we have too many X characters. int pos = returnString.IndexOf("XXXX"); if (pos >= 0) { - int xPos = returnString.IndexOf("L"); + int xPos = returnString.IndexOf("L"); if (xPos >= 0 & xPos == pos - 1) returnString = returnString.Replace("LXXXX", "XC"); else - returnString = returnString.Replace("XXXX", "XL"); + returnString = returnString.Replace("XXXX", "XL"); } // Check whether we have too many I characters pos = returnString.IndexOf("IIII"); @@ -67,10 +67,10 @@ public string Format(String format, Object obj, IFormatProvider provider) if (returnString.IndexOf("V") >= 0) returnString = returnString.Replace("VIIII", "IX"); else - returnString = returnString.Replace("IIII", "IV"); + returnString = returnString.Replace("IIII", "IV"); - return returnString; - } + return returnString; + } // Use default for all other formatting. if (obj is IFormattable) @@ -89,11 +89,11 @@ public static void Main() DateTime day = DateTime.Now; InterceptProvider provider = new InterceptProvider(); Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day)); - Console.WriteLine(String.Format(provider, "{0}: {1:F}\n", "Today: ", + Console.WriteLine(String.Format(provider, "{0}: {1:F}\n", "Today: ", (DayOfWeek) DateTime.Now.DayOfWeek)); - Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n", + Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n", (Byte) 2, (Byte) 12, (Byte) 199)); - Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}\n", + Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}\n", (Byte) 2, (Byte) 12, (Byte) 199)); } } @@ -102,16 +102,16 @@ public static void Main() // Provider: InterceptProvider, Object: 16.935, Format String: C2 // Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d // 10: $16.94 on 1/31/2013 -// +// // Provider: InterceptProvider, Object: Today: , Format String: // Provider: InterceptProvider, Object: Thursday, Format String: F // Today: : Thursday -// +// // Provider: InterceptProvider, Object: 2, Format String: X // Provider: InterceptProvider, Object: 12, Format String: // Provider: InterceptProvider, Object: 199, Format String: // 2, 12, 199 -// +// // Provider: InterceptProvider, Object: 2, Format String: R // Provider: InterceptProvider, Object: 12, Format String: R // Provider: InterceptProvider, Object: 199, Format String: R diff --git a/snippets/csharp/System/FormatException/Overview/qa26.cs b/snippets/csharp/System/FormatException/Overview/qa26.cs index 372f1370470..9e8ab231866 100644 --- a/snippets/csharp/System/FormatException/Overview/qa26.cs +++ b/snippets/csharp/System/FormatException/Overview/qa26.cs @@ -1,6 +1,6 @@ using System; -public class Example7 +public class QAExample26 { public static void Main() { @@ -15,9 +15,9 @@ public static void Main() } // The example displays output like the following: // $1,603.00 1.603E+003 1603.0000 1,603.000 16.03 % - // + // // $1,794.68 1.795E+003 1794.6824 1,794.682 17.95 % - // + // // $15,436.14 1.544E+004 15436.1400 15,436.140 154.36 % // } diff --git a/snippets/csharp/System/FormatException/Overview/qa27.cs b/snippets/csharp/System/FormatException/Overview/qa27.cs index 403a9da46af..baaa13876bb 100644 --- a/snippets/csharp/System/FormatException/Overview/qa27.cs +++ b/snippets/csharp/System/FormatException/Overview/qa27.cs @@ -1,6 +1,6 @@ using System; -public class Example8 +public class QAExample27 { public static void Main() { diff --git a/snippets/csharp/System/FormatException/Overview/qa28.cs b/snippets/csharp/System/FormatException/Overview/qa28.cs index acd3e998104..548c3bd924a 100644 --- a/snippets/csharp/System/FormatException/Overview/qa28.cs +++ b/snippets/csharp/System/FormatException/Overview/qa28.cs @@ -1,6 +1,6 @@ using System; -public class Example9 +public class QAExample28 { public static void Main() { diff --git a/snippets/csharp/System/FormatException/Overview/qa29.cs b/snippets/csharp/System/FormatException/Overview/qa29.cs index 33faef50db8..47079a46061 100644 --- a/snippets/csharp/System/FormatException/Overview/qa29.cs +++ b/snippets/csharp/System/FormatException/Overview/qa29.cs @@ -1,6 +1,6 @@ using System; -public class Example10 +public class QAExample29 { public static void Main() { diff --git a/snippets/csharp/System/FormatException/Overview/qa3.cs b/snippets/csharp/System/FormatException/Overview/qa3.cs index a599a1e270f..a6ad80f625f 100644 --- a/snippets/csharp/System/FormatException/Overview/qa3.cs +++ b/snippets/csharp/System/FormatException/Overview/qa3.cs @@ -26,7 +26,7 @@ public static void WillThrow() Console.WriteLine("FormatException"); } } - + public static void WontThrow() { // @@ -38,7 +38,7 @@ public static void WontThrow() Console.WriteLine(result); // } - + public static void Recommended() { // diff --git a/snippets/fsharp/System/AppContext/Overview/Example4.fs b/snippets/fsharp/System/AppContext/Overview/Example4.fs new file mode 100644 index 00000000000..7aca0ebeb08 --- /dev/null +++ b/snippets/fsharp/System/AppContext/Overview/Example4.fs @@ -0,0 +1,30 @@ +module Example4 + +// +open System +open System.Reflection + +[] +do () + +module StringLibrary = + let substringStartsAt (fullString: string) (substr: string) = + fullString.IndexOf(substr, StringComparison.Ordinal) + +// + +// +let value = "The archaeologist" +let substring = "archæ" + +let position = + StringLibrary.substringStartsAt value substring + +if position >= 0 then + printfn $"'{substring}' found in '{value}' starting at position {position}" +else + printfn $"'{substring}' not found in '{value}'" + +// The example displays the following output: +// 'archæ' not found in 'The archaeologist' +// diff --git a/snippets/fsharp/System/AppContext/Overview/Example6.fs b/snippets/fsharp/System/AppContext/Overview/Example6.fs new file mode 100644 index 00000000000..32aefd261fd --- /dev/null +++ b/snippets/fsharp/System/AppContext/Overview/Example6.fs @@ -0,0 +1,30 @@ +module Example6 + +// +open System +open System.Reflection + +[] +do () + +module StringLibrary = + let substringStartsAt (fullString: string) (substr: string) = + fullString.IndexOf(substr, StringComparison.CurrentCulture) + +// + +// +let value = "The archaeologist" +let substring = "archæ" + +let position = + StringLibrary.substringStartsAt value substring + +if position >= 0 then + printfn $"'{substring}' found in '{value}' starting at position {position}" +else + printfn $"'{substring}' not found in '{value}'" + +// The example displays the following output: +// 'archæ' found in 'The archaeologist' starting at position 4 +// \ No newline at end of file diff --git a/snippets/fsharp/System/AppContext/Overview/Example8.fs b/snippets/fsharp/System/AppContext/Overview/Example8.fs new file mode 100644 index 00000000000..5b4f8b2691a --- /dev/null +++ b/snippets/fsharp/System/AppContext/Overview/Example8.fs @@ -0,0 +1,18 @@ +module Example8 + +// +open System +open System.Reflection + +[] +do () + +AppContext.SetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison",true) + +module StringLibrary = + let substringStartsAt (fullString: string) (substr: string) = + match AppContext.TryGetSwitch "StringLibrary.DoNotUseCultureSensitiveComparison" with + | true, true -> fullString.IndexOf(substr, StringComparison.Ordinal) + | _ -> fullString.IndexOf(substr, StringComparison.CurrentCulture) + +// \ No newline at end of file diff --git a/snippets/fsharp/System/Byte/Overview/bitwise1.fs b/snippets/fsharp/System/Byte/Overview/bitwise1.fs new file mode 100644 index 00000000000..5226be1e856 --- /dev/null +++ b/snippets/fsharp/System/Byte/Overview/bitwise1.fs @@ -0,0 +1,22 @@ +module bitwise1 + +// +open System +open System.Globalization + +let values = + [ Convert.ToString(12, 16) + Convert.ToString(123, 16) + Convert.ToString(245, 16) ] + +let mask = 0xFEuy +for value in values do + let byteValue = Byte.Parse(value, NumberStyles.AllowHexSpecifier) + printfn $"{byteValue} And {mask} = {byteValue &&& mask}" + + +// The example displays the following output: +// 12 And 254 = 12 +// 123 And 254 = 122 +// 245 And 254 = 244 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Byte/Overview/bitwise2.fs b/snippets/fsharp/System/Byte/Overview/bitwise2.fs new file mode 100644 index 00000000000..210dbdbb06b --- /dev/null +++ b/snippets/fsharp/System/Byte/Overview/bitwise2.fs @@ -0,0 +1,33 @@ +module bitwise2 + +// +open System +open System.Collections.Generic +open System.Globalization + +[] +type ByteString = + { Sign: int + Value: string } + +let createArray values = + [ for value in values do + let sign = sign value + { Sign = sign + // Change two's complement to magnitude-only representation. + Value = Convert.ToString(value * sign, 16)} ] + + +let values = createArray [ -15; 123; 245 ] + +let mask = 0x14uy // Mask all bits but 2 and 4. + +for strValue in values do + let byteValue = Byte.Parse(strValue.Value, NumberStyles.AllowHexSpecifier) + printfn $"{strValue.Sign * int byteValue} ({Convert.ToString(byteValue, 2)}) And {mask} ({Convert.ToString(mask, 2)}) = {(strValue.Sign &&& (int mask |> sign)) * int (byteValue &&& mask)} ({Convert.ToString(byteValue &&& mask, 2)})" + +// The example displays the following output: +// -15 (1111) And 20 (10100) = 4 (100) +// 123 (1111011) And 20 (10100) = 16 (10000) +// 245 (11110101) And 20 (10100) = 20 (10100) +// \ No newline at end of file diff --git a/snippets/fsharp/System/Byte/Overview/byteinstantiation1.fs b/snippets/fsharp/System/Byte/Overview/byteinstantiation1.fs new file mode 100644 index 00000000000..73d3855f0ae --- /dev/null +++ b/snippets/fsharp/System/Byte/Overview/byteinstantiation1.fs @@ -0,0 +1,56 @@ +open System + +let ``instantiate by assignment`` = + // + let value1 = 64uy + let value2 = 255uy + // + () + +let ``instantiateByNarrowingConversion`` = + // + let int1 = 128 + try + let value1 = byte int1 + printfn $"{value1}" + with :? OverflowException -> + printfn $"{int1} is out of range of a byte." + + let dbl2 = 3.997 + try + let value2 = byte dbl2 + printfn $"{value2}" + with :? OverflowException -> + printfn $"{dbl2} is out of range of a byte." + + // The example displays the following output: + // 128 + // 3 + // + +let parse = + // + let string1 = "244" + try + let byte1 = Byte.Parse string1 + printfn $"{byte1}" + with + | :? OverflowException -> + printfn $"'{string1}' is out of range of a byte." + | :? FormatException -> + printfn $"'{string1}' is out of range of a byte." + + let string2 = "F9" + try + let byte2 = Byte.Parse(string2, System.Globalization.NumberStyles.HexNumber) + printfn $"{byte2}" + with + | :? OverflowException -> + printfn $"'{string2}' is out of range of a byte." + | :? FormatException -> + printfn $"'{string2}' is out of range of a byte." + + // The example displays the following output: + // 244 + // 249 + // \ No newline at end of file diff --git a/snippets/fsharp/System/Byte/Overview/formatting1.fs b/snippets/fsharp/System/Byte/Overview/formatting1.fs new file mode 100644 index 00000000000..270bf0e8291 --- /dev/null +++ b/snippets/fsharp/System/Byte/Overview/formatting1.fs @@ -0,0 +1,47 @@ +open System + +let callToString () = + // + let numbers = [| 0; 16; 104; 213 |] + for number in numbers do + // Display value using default formatting. + number.ToString() + |> printf "%-3s --> " + + // Display value with 3 digits and leading zeros. + number.ToString "D3" + |> printf "%s " + + // Display value with hexadecimal. + number.ToString "X2" + |> printf "%s " + + // Display value with four hexadecimal digits. + number.ToString "X4" + |> printfn "%s" + + // The example displays the following output: + // 0 --> 000 00 0000 + // 16 --> 016 10 0010 + // 104 --> 104 68 0068 + // 213 --> 213 D5 00D5 + // + +let callConvert () = + // + let numbers = [| 0; 16; 104; 213 |] + printfn "%s %8s %5s %5s" "Value" "Binary" "Octal" "Hex" + for number in numbers do + printfn $"%5i{number} %8s{Convert.ToString(number, 2)} %5s{Convert.ToString(number, 8)} %5s{Convert.ToString(number, 16)}" + + // The example displays the following output: + // Value Binary Octal Hex + // 0 0 0 0 + // 16 10000 20 10 + // 104 1101000 150 68 + // 213 11010101 325 d5 + // + +callToString () +printfn "-----" +callConvert () \ No newline at end of file diff --git a/snippets/fsharp/System/Char/Overview/GetUnicodeCategory3.fs b/snippets/fsharp/System/Char/Overview/GetUnicodeCategory3.fs new file mode 100644 index 00000000000..eb5ad2ae777 --- /dev/null +++ b/snippets/fsharp/System/Char/Overview/GetUnicodeCategory3.fs @@ -0,0 +1,68 @@ +module GetUnicodeCategory3 + +// +open System + +// Define a string with a variety of character categories. +let s = "The red car drove down the long, narrow, secluded road." +// Determine the category of each character. +for ch in s do + printfn $"'{ch}': {Char.GetUnicodeCategory ch}" + +// The example displays the following output: +// 'T': UppercaseLetter +// 'h': LowercaseLetter +// 'e': LowercaseLetter +// ' ': SpaceSeparator +// 'r': LowercaseLetter +// 'e': LowercaseLetter +// 'd': LowercaseLetter +// ' ': SpaceSeparator +// 'c': LowercaseLetter +// 'a': LowercaseLetter +// 'r': LowercaseLetter +// ' ': SpaceSeparator +// 'd': LowercaseLetter +// 'r': LowercaseLetter +// 'o': LowercaseLetter +// 'v': LowercaseLetter +// 'e': LowercaseLetter +// ' ': SpaceSeparator +// 'd': LowercaseLetter +// 'o': LowercaseLetter +// 'w': LowercaseLetter +// 'n': LowercaseLetter +// ' ': SpaceSeparator +// 't': LowercaseLetter +// 'h': LowercaseLetter +// 'e': LowercaseLetter +// ' ': SpaceSeparator +// 'l': LowercaseLetter +// 'o': LowercaseLetter +// 'n': LowercaseLetter +// 'g': LowercaseLetter +// ',': OtherPunctuation +// ' ': SpaceSeparator +// 'n': LowercaseLetter +// 'a': LowercaseLetter +// 'r': LowercaseLetter +// 'r': LowercaseLetter +// 'o': LowercaseLetter +// 'w': LowercaseLetter +// ',': OtherPunctuation +// ' ': SpaceSeparator +// 's': LowercaseLetter +// 'e': LowercaseLetter +// 'c': LowercaseLetter +// 'l': LowercaseLetter +// 'u': LowercaseLetter +// 'd': LowercaseLetter +// 'e': LowercaseLetter +// 'd': LowercaseLetter +// ' ': SpaceSeparator +// 'r': LowercaseLetter +// 'o': LowercaseLetter +// 'a': LowercaseLetter +// 'd': LowercaseLetter +// '.': OtherPunctuation +// \ No newline at end of file diff --git a/snippets/fsharp/System/Char/Overview/grapheme1.fs b/snippets/fsharp/System/Char/Overview/grapheme1.fs new file mode 100644 index 00000000000..8cb8c8aad6f --- /dev/null +++ b/snippets/fsharp/System/Char/Overview/grapheme1.fs @@ -0,0 +1,15 @@ +module grapheme1 + +// +open System +open System.IO + +let sw = new StreamWriter("chars1.txt") +let chars = [| '\u0061'; '\u0308' |] +let string = String chars +sw.WriteLine string +sw.Close() + +// The example produces the following output: +// ä +// \ No newline at end of file diff --git a/snippets/fsharp/System/Char/Overview/normalized.fs b/snippets/fsharp/System/Char/Overview/normalized.fs new file mode 100644 index 00000000000..820606350eb --- /dev/null +++ b/snippets/fsharp/System/Char/Overview/normalized.fs @@ -0,0 +1,23 @@ +module normalized + +// +open System + +let showString (s: string) = + printf $"Length of string: {s.Length} (" + for i = 0 to s.Length - 1 do + printf $"U+{Convert.ToUInt16 s[i]:X4}" + if i <> s.Length - 1 then printf " " + printfn ")\n" + +let combining = "\u0061\u0308" +showString combining + +let normalized = combining.Normalize() +showString normalized + +// The example displays the following output: +// Length of string: 2 (U+0061 U+0308) +// +// Length of string: 1 (U+00E4) +// \ No newline at end of file diff --git a/snippets/fsharp/System/Char/Overview/surrogate1.fs b/snippets/fsharp/System/Char/Overview/surrogate1.fs new file mode 100644 index 00000000000..33bf60c0330 --- /dev/null +++ b/snippets/fsharp/System/Char/Overview/surrogate1.fs @@ -0,0 +1,22 @@ +module surrogate1 + +// +open System +open System.IO + +let showCodePoints (value: char seq) = + let str = + value + |> Seq.map (fun ch -> $"U+{Convert.ToUInt16 ch:X4}") + |> String.concat "" + str.Trim() + +let sw = new StreamWriter(@".\chars2.txt") +let utf32 = 0x1D160 +let surrogate = Char.ConvertFromUtf32 utf32 +sw.WriteLine $"U+{utf32:X6} UTF-32 = {surrogate} ({showCodePoints surrogate}) UTF-16" +sw.Close() + +// The example produces the following output: +// U+01D160 UTF-32 = ð (U+D834 U+DD60) UTF-16 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Char/Overview/textelements2.fs b/snippets/fsharp/System/Char/Overview/textelements2.fs new file mode 100644 index 00000000000..5006ace1d57 --- /dev/null +++ b/snippets/fsharp/System/Char/Overview/textelements2.fs @@ -0,0 +1,16 @@ +module textelements2 + +// +open System + +let result = + [ for i in 0x10107..0x10110 do // Range of Aegean numbers. + Char.ConvertFromUtf32 i ] + |> String.concat "" + +printfn $"The string contains {result.Length} characters." + + +// The example displays the following output: +// The string contains 20 characters. +// \ No newline at end of file diff --git a/snippets/fsharp/System/Char/Overview/textelements2a.fs b/snippets/fsharp/System/Char/Overview/textelements2a.fs new file mode 100644 index 00000000000..a7e6ae71aaf --- /dev/null +++ b/snippets/fsharp/System/Char/Overview/textelements2a.fs @@ -0,0 +1,18 @@ +module textelements2a + +// +open System +open System.Globalization + +let result = + [ for i in 0x10107..0x10110 do // Range of Aegean numbers. + Char.ConvertFromUtf32 i ] + |> String.concat "" + + +let si = StringInfo result +printfn $"The string contains {si.LengthInTextElements} characters." + +// The example displays the following output: +// The string contains 10 characters. +// \ No newline at end of file diff --git a/snippets/fsharp/System/Console/Overview/example3.fs b/snippets/fsharp/System/Console/Overview/example3.fs new file mode 100644 index 00000000000..5ff62571827 --- /dev/null +++ b/snippets/fsharp/System/Console/Overview/example3.fs @@ -0,0 +1,163 @@ +// dump a range of Unicode characters as a 16x16 array +// +module DisplayChars + +open System +open System.IO +open System.Globalization +open System.Text + +type uint = uint32 + +let inline roundDownToMultipleOf b u = u - (u % b) + +let inline roundUpToMultipleOf b u = roundDownToMultipleOf b u |> (+) b + +let displayRange (start: uint) (``end``: uint) = + + let upperRange = 0x10FFFFu + let surrogateStart = 0xD800u + let surrogateEnd = 0xDFFFu + + let start, ``end`` = + if ``end`` <= start then ``end``, start + else start, ``end`` + + // Check whether the start or end range is outside of last plane. + if start > upperRange then + invalidArg "start" + (String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{1:X5})", start, upperRange)) + if ``end`` > upperRange then + invalidArg "end" + (String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{0:X5})", ``end``, upperRange)) + + // Since we're using 21-bit code points, we can't use U+D800 to U+DFFF. + if (start < surrogateStart && ``end`` > surrogateStart) || (start >= surrogateStart && start <= surrogateEnd) then + raise + (ArgumentException + (String.Format + ("0x{0:X5}-0x{1:X5} includes the surrogate pair range 0x{2:X5}-0x{3:X5}", start, ``end``, + surrogateStart, surrogateEnd))) + let last = roundUpToMultipleOf 0x10u ``end`` + let first = roundDownToMultipleOf 0x10u start + + let rows = (last - first) / 0x10u + + for r in 0u .. (rows - 1u) do + // Display the row header. + printf "%05x " (first + 0x10u * r) + + for c in 0u .. (0x10u - 1u) do + let cur = (first + 0x10u * r + c) + if cur < start || ``end`` < cur then + printf " %c " (Convert.ToChar 0x20) + else + // the cast to int is safe, since we know that val <= upperRange. + let chars = Char.ConvertFromUtf32(int cur) + // Display a space for code points that are not valid characters. + if CharUnicodeInfo.GetUnicodeCategory(chars[0]) = UnicodeCategory.OtherNotAssigned then + printf " %c " (Convert.ToChar 0x20) + else + // Display a space for code points in the private use area. + if CharUnicodeInfo.GetUnicodeCategory(chars[0]) = UnicodeCategory.PrivateUse then + printf " %c " (Convert.ToChar 0x20) + else if chars.Length > 1 + && CharUnicodeInfo.GetUnicodeCategory(chars, 0) = UnicodeCategory.OtherNotAssigned then + printf " %c " (Convert.ToChar 0x20) + else printf " %s " chars + + match c with + | 3u + | 11u -> printf "-" + | 7u -> printf "--" + | _ -> () + + Console.WriteLine() + if (0u < r && r % 0x10u = 0u) then Console.WriteLine() + + + +[] +let main args = + // Get the current encoding so we can restore it. + let originalOutputEncoding = Console.OutputEncoding + + try + try + let parsedArgs = + match args.Length with + | 2 -> + Some + {| setOutputEncodingToUnicode = true + rangeStart = uint.Parse(args[0], NumberStyles.HexNumber) + rangeEnd = uint.Parse(args[1], NumberStyles.HexNumber) |} + | 3 -> + let parseHexNumberOrThrow (value: string) parameterName = + (uint.TryParse(value, NumberStyles.HexNumber, null)) + |> function + | (false, _) -> + invalidArg parameterName (String.Format("{0} is not a valid hexadecimal number.", value)) + | (true, value) -> value + + let setOutputEncodingToUnicode = + match bool.TryParse args[2] with + | true, value -> value + | false, _ -> true + + Some + {| setOutputEncodingToUnicode = setOutputEncodingToUnicode + rangeStart = parseHexNumberOrThrow args[0] "rangeStart" + rangeEnd = parseHexNumberOrThrow args[1] "rangeEnd" |} + | _ -> + printfn "Usage: %s <%s> <%s> [%s]" (Environment.GetCommandLineArgs()[0]) "startingCodePointInHex" + "endingCodePointInHex" "" + None + + match parsedArgs with + | None -> () + | Some parsedArgs -> + if parsedArgs.setOutputEncodingToUnicode then + // This won't work before .NET Framework 4.5. + try + // Set encoding using endianness of this system. + // We're interested in displaying individual Char objects, so + // we don't want a Unicode BOM or exceptions to be thrown on + // invalid Char values. + Console.OutputEncoding <- UnicodeEncoding(not BitConverter.IsLittleEndian, false) + printfn "\nOutput encoding set to UTF-16" + + with :? IOException -> + printfn "Output encoding set to UTF-8" + Console.OutputEncoding <- UTF8Encoding() + else + printfn "The console encoding is %s (code page %i)" (Console.OutputEncoding.EncodingName) + (Console.OutputEncoding.CodePage) + + displayRange parsedArgs.rangeStart parsedArgs.rangeEnd + with :? ArgumentException as ex -> Console.WriteLine(ex.Message) + finally + // Restore console environment. + Console.OutputEncoding <- originalOutputEncoding + 0 + +// If the example is run with the command line +// DisplayChars 0400 04FF true +// the example displays the Cyrillic character set as follows: +// Output encoding set to UTF-16 +// 00400 Ѐ Ё Ђ Ѓ - Є Ѕ І Ї -- Ј Љ Њ Ћ - Ќ Ѝ Ў Џ +// 00410 А Б В Г - Д Е Ж З -- И Й К Л - М Н О П +// 00420 Р С Т У - Ф Х Ц Ч -- Ш Щ Ъ Ы - Ь Э Ю Я +// 00430 а б в г - д е ж з -- и й к л - м н о п +// 00440 р с т у - ф х ц ч -- ш щ ъ ы - ь э ю я +// 00450 ѐ ё ђ ѓ - є ѕ і ї -- ј љ њ ћ - ќ ѝ ў џ +// 00460 Ѡ ѡ Ѣ ѣ - Ѥ ѥ Ѧ ѧ -- Ѩ ѩ Ѫ ѫ - Ѭ ѭ Ѯ ѯ +// 00470 Ѱ ѱ Ѳ ѳ - Ѵ ѵ Ѷ ѷ -- Ѹ ѹ Ѻ ѻ - Ѽ ѽ Ѿ ѿ +// 00480 Ҁ ҁ ҂ ҃ - ҄ ҅ ҆ ҇ -- ҈ ҉ Ҋ ҋ - Ҍ ҍ Ҏ ҏ +// 00490 Ґ ґ Ғ ғ - Ҕ ҕ Җ җ -- Ҙ ҙ Қ қ - Ҝ ҝ Ҟ ҟ +// 004a0 Ҡ ҡ Ң ң - Ҥ ҥ Ҧ ҧ -- Ҩ ҩ Ҫ ҫ - Ҭ ҭ Ү ү +// 004b0 Ұ ұ Ҳ ҳ - Ҵ ҵ Ҷ ҷ -- Ҹ ҹ Һ һ - Ҽ ҽ Ҿ ҿ +// 004c0 Ӏ Ӂ ӂ Ӄ - ӄ Ӆ ӆ Ӈ -- ӈ Ӊ ӊ Ӌ - ӌ Ӎ ӎ ӏ +// 004d0 Ӑ ӑ Ӓ ӓ - Ӕ ӕ Ӗ ӗ -- Ә ә Ӛ ӛ - Ӝ ӝ Ӟ ӟ +// 004e0 Ӡ ӡ Ӣ ӣ - Ӥ ӥ Ӧ ӧ -- Ө ө Ӫ ӫ - Ӭ ӭ Ӯ ӯ +// 004f0 Ӱ ӱ Ӳ ӳ - Ӵ ӵ Ӷ ӷ -- Ӹ ӹ Ӻ ӻ - Ӽ ӽ Ӿ ӿ +// diff --git a/snippets/fsharp/System/Console/Overview/fontlink1.fs b/snippets/fsharp/System/Console/Overview/fontlink1.fs new file mode 100644 index 00000000000..7fe8c63e546 --- /dev/null +++ b/snippets/fsharp/System/Console/Overview/fontlink1.fs @@ -0,0 +1,54 @@ +module fontlink1 + +// +open System +open Microsoft.Win32 + +let valueName = "Lucida Console" +let newFont = "simsun.ttc,SimSun" + +let key = + Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink", true) +if isNull key then + printfn "Font linking is not enabled." +else + // Determine if the font is a base font. + let names = key.GetValueNames() + + let (fonts, kind, toAdd) = + if names |> Array.exists (fun s -> s.Equals(valueName, StringComparison.OrdinalIgnoreCase)) then + // Get the value's type. + let kind = key.GetValueKind(valueName) + + // Type should be RegistryValueKind.MultiString, but we can't be sure. + let fonts = + match kind with + | RegistryValueKind.String -> [| key.GetValue(valueName) :?> string |] + | RegistryValueKind.MultiString -> (key.GetValue(valueName) :?> string array) + | _ -> [||] + + // Determine whether SimSun is a linked font. + let toAdd = + not (fonts |> Array.exists (fun s -> s.IndexOf("SimSun", StringComparison.OrdinalIgnoreCase) >= 0)) + + (fonts, kind, toAdd) + else + // Font is not a base font. + ([||], RegistryValueKind.Unknown, true) + + if toAdd then + // Font is not a linked font. + let newFonts = Array.append fonts [| newFont |] + + // Change REG_SZ to REG_MULTI_SZ. + if kind = RegistryValueKind.String then key.DeleteValue(valueName, false) + + key.SetValue(valueName, newFonts, RegistryValueKind.MultiString) + printfn "SimSun added to the list of linked fonts." + else + printfn "Font is already linked." + + +if not (isNull key) then key.Close() + +// diff --git a/snippets/fsharp/System/Console/Overview/normalize1.fs b/snippets/fsharp/System/Console/Overview/normalize1.fs new file mode 100644 index 00000000000..48d57694c8e --- /dev/null +++ b/snippets/fsharp/System/Console/Overview/normalize1.fs @@ -0,0 +1,18 @@ +module normalize1 + +// +open System + +let chars = [| '\u0061'; '\u0308' |] + +let combining = String chars +Console.WriteLine combining + +let combining2 = combining.Normalize() +Console.WriteLine combining2 + + +// The example displays the following output: +// a" +// ä +// diff --git a/snippets/fsharp/System/Console/Overview/setfont1.fs b/snippets/fsharp/System/Console/Overview/setfont1.fs new file mode 100644 index 00000000000..01305d3cb8b --- /dev/null +++ b/snippets/fsharp/System/Console/Overview/setfont1.fs @@ -0,0 +1,74 @@ +// +module Example + +open System +open System.Runtime.InteropServices + +[] +let STD_OUTPUT_HANDLE = -11 + +[] +let TMPF_TRUETYPE = 4 + +[] +let LF_FACESIZE = 32 + +let INVALID_HANDLE_VALUE = IntPtr(-1) + + +[] +[] +type COORD = + val mutable X: int16 + val mutable Y: int16 + + internal new(x: int16, y: int16) = + { X = x + Y = y } + +[] +[] +type CONSOLE_FONT_INFO_EX = + val mutable cbSize: uint32 + val mutable nFont: uint32 + val mutable dwFontSize: COORD + val mutable FontFamily: int + val mutable FontWeight: int + [] + val mutable FaceName: string + +[] +extern IntPtr GetStdHandle(int nStdHandle) + +[] +extern bool GetCurrentConsoleFontEx(IntPtr consoleOutput, bool maximumWindow, CONSOLE_FONT_INFO_EX lpConsoleCurrentFontEx) + +[] +extern bool SetCurrentConsoleFontEx(IntPtr consoleOutput, bool maximumWindow, CONSOLE_FONT_INFO_EX consoleCurrentFontEx) + +[] +let main argv = + let fontName = "Lucida Console" + let hnd = GetStdHandle(STD_OUTPUT_HANDLE) + if hnd <> INVALID_HANDLE_VALUE then + let mutable info = CONSOLE_FONT_INFO_EX() + info.cbSize <- uint32 (Marshal.SizeOf(info)) + // First determine whether there's already a TrueType font. + if (GetCurrentConsoleFontEx(hnd, false, info)) then + if (((info.FontFamily) &&& TMPF_TRUETYPE) = TMPF_TRUETYPE) then + Console.WriteLine("The console already is using a TrueType font.") + else + // Set console font to Lucida Console. + let mutable newInfo = CONSOLE_FONT_INFO_EX() + newInfo.cbSize <- uint32 (Marshal.SizeOf(newInfo)) + newInfo.FontFamily <- TMPF_TRUETYPE + newInfo.FaceName <- fontName + // Get some settings from current font. + newInfo.dwFontSize <- COORD(info.dwFontSize.X, info.dwFontSize.Y) + newInfo.FontWeight <- info.FontWeight + SetCurrentConsoleFontEx(hnd, false, newInfo) |> ignore + Console.WriteLine("The console is now using a TrueType font.") + + // Return zero for success + 0 +// diff --git a/snippets/fsharp/System/Console/Overview/source.fs b/snippets/fsharp/System/Console/Overview/source.fs new file mode 100644 index 00000000000..7e427b2bfb6 --- /dev/null +++ b/snippets/fsharp/System/Console/Overview/source.fs @@ -0,0 +1,21 @@ +// +module Example + +open System + +[] +let main argv = + Console.Write("Hello ") + Console.WriteLine("World!") + Console.Write("Enter your name: ") + let name = Console.ReadLine() + Console.Write("Good day, ") + Console.Write(name) + Console.WriteLine("!") + 0 + +// The example displays output similar to the following: +// Hello World! +// Enter your name: James +// Good day, James! +// diff --git a/snippets/fsharp/System/Console/Overview/unicode1.fs b/snippets/fsharp/System/Console/Overview/unicode1.fs new file mode 100644 index 00000000000..d1b15f28c57 --- /dev/null +++ b/snippets/fsharp/System/Console/Overview/unicode1.fs @@ -0,0 +1,23 @@ +module unicode1 +// +open System + +// Create a char List for the modern Cyrillic alphabet, +// from U+0410 to U+044F. +let chars = + [ for codePoint in 0x0410 .. 0x044F do + Convert.ToChar codePoint ] + +printfn "Current code page: %i\n" Console.OutputEncoding.CodePage +// Display the characters. +for ch in chars do + printf "%c " ch + if Console.CursorLeft >= 70 then Console.WriteLine() + +// The example displays the following output: +// Current code page: 437 +// +// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? +// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? +// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? +// \ No newline at end of file diff --git a/snippets/fsharp/System/DateTime/FromBinary/frombinary1.fs b/snippets/fsharp/System/DateTime/FromBinary/frombinary1.fs new file mode 100644 index 00000000000..2a6c752eda8 --- /dev/null +++ b/snippets/fsharp/System/DateTime/FromBinary/frombinary1.fs @@ -0,0 +1,15 @@ +// +open System + +let localDate = DateTime(2010, 3, 14, 2, 30, 0, DateTimeKind.Local) +let binLocal = localDate.ToBinary() +if TimeZoneInfo.Local.IsInvalidTime localDate then + printfn $"{localDate} is an invalid time in the {TimeZoneInfo.Local.StandardName} zone." + +let localDate2 = DateTime.FromBinary binLocal +printfn $"{localDate} = {localDate2}: {localDate.Equals localDate2}" + +// The example displays the following output: +// 3/14/2010 2:30:00 AM is an invalid time in the Pacific Standard Time zone. +// 3/14/2010 2:30:00 AM = 3/14/2010 3:30:00 AM: False +// \ No newline at end of file diff --git a/snippets/fsharp/System/DateTime/Overview/Calendar.fs b/snippets/fsharp/System/DateTime/Overview/Calendar.fs new file mode 100644 index 00000000000..34ad331aa26 --- /dev/null +++ b/snippets/fsharp/System/DateTime/Overview/Calendar.fs @@ -0,0 +1,108 @@ +module Calender + +open System + +let thaiBuddistEra () = + // + let thTH = System.Globalization.CultureInfo "th-TH" + let value = DateTime(2016, 5, 28) + + printfn $"{value.ToString thTH}" + + thTH.DateTimeFormat.Calendar <- System.Globalization.GregorianCalendar() + + printfn $"{value.ToString thTH}" + + // The example displays the following output: + // 28/5/2559 0:00:00 + // 28/5/2016 0:00:00 + // + +let thaiBuddhistEraParse () = + // + let thTH = System.Globalization.CultureInfo "th-TH" + let value = DateTime.Parse("28/05/2559", thTH) + printfn $"{value.ToString thTH}" + + thTH.DateTimeFormat.Calendar <- System.Globalization.GregorianCalendar() + printfn $"{value.ToString thTH}" + + // The example displays the following output: + // 28/5/2559 0:00:00 + // 28/5/2016 0:00:00 + // + +let instantiateCalendar () = + // + let thTH = System.Globalization.CultureInfo "th-TH" + let dat = DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar) + + printfn $"""Thai Buddhist era date: {dat.ToString("d", thTH)}""" + printfn $"Gregorian date: {dat:d}" + + // The example displays the following output: + // Thai Buddhist Era Date: 28/5/2559 + // Gregorian Date: 28/05/2016 + // + +let calendarFields () = + // + let thTH = System.Globalization.CultureInfo "th-TH" + let cal = thTH.DateTimeFormat.Calendar + let dat = DateTime(2559, 5, 28, cal) + printfn "Using the Thai Buddhist Era calendar:" + printfn $"""Date: {dat.ToString("d", thTH)}""" + printfn $"Year: {cal.GetYear dat}" + printfn $"Leap year: {cal.IsLeapYear(cal.GetYear dat)}\n" + + printfn "Using the Gregorian calendar:" + printfn $"Date: {dat:d}" + printfn $"Year: {dat.Year}" + printfn $"Leap year: {DateTime.IsLeapYear dat.Year}" + + // The example displays the following output: + // Using the Thai Buddhist Era calendar + // Date : 28/5/2559 + // Year: 2559 + // Leap year : True + // + // Using the Gregorian calendar + // Date : 28/05/2016 + // Year: 2016 + // Leap year : True + // + +let calculateWeeks () = + // + let thTH = System.Globalization.CultureInfo "th-TH" + let thCalendar = thTH.DateTimeFormat.Calendar + let dat = DateTime(1395, 8, 18, thCalendar) + printfn "Using the Thai Buddhist Era calendar:" + printfn $"""Date: {dat.ToString("d", thTH)}""" + printfn $"Day of Week: {thCalendar.GetDayOfWeek dat}" + printfn $"Week of year: {thCalendar.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}\n" + + let greg = System.Globalization.GregorianCalendar() + printfn "Using the Gregorian calendar:" + printfn $"Date: {dat:d}" + printfn $"Day of Week: {dat.DayOfWeek}" + printfn $"Week of year: {greg.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}" + + // The example displays the following output: + // Using the Thai Buddhist Era calendar + // Date : 18/8/1395 + // Day of Week: Sunday + // Week of year: 34 + // + // Using the Gregorian calendar + // Date : 18/08/0852 + // Day of Week: Sunday + // Week of year: 34 + // + + +thaiBuddistEra () +thaiBuddhistEraParse () +instantiateCalendar () +calendarFields () +calculateWeeks () \ No newline at end of file diff --git a/snippets/fsharp/System/DateTime/Overview/DateTimeComparisons.fs b/snippets/fsharp/System/DateTime/Overview/DateTimeComparisons.fs new file mode 100644 index 00000000000..0ad8d7bcc88 --- /dev/null +++ b/snippets/fsharp/System/DateTime/Overview/DateTimeComparisons.fs @@ -0,0 +1,53 @@ +module DateTimeComparisons + +open System +open System.Text + +// +let roughlyEquals (time: DateTime) (timeWithWindow: DateTime) windowInSeconds frequencyInSeconds = + let delta = + int64 (timeWithWindow - time).TotalSeconds % frequencyInSeconds + + let delta = if delta > windowInSeconds then frequencyInSeconds - delta else delta + abs delta < windowInSeconds + +let testRoughlyEquals () = + let window = 10 + let window' = 10. + let freq = 60 * 60 * 2 // 2 hours + + let d1 = DateTime.Now + + let d2 = d1.AddSeconds(2. * window') + let d3 = d1.AddSeconds(-2. * window') + let d4 = d1.AddSeconds(window' / 2.) + let d5 = d1.AddSeconds(-window' / 2.) + + let d6 = (d1.AddHours 2).AddSeconds(2. * window') + let d7 = (d1.AddHours 2).AddSeconds(-2. * window') + let d8 = (d1.AddHours 2).AddSeconds(window' / 2.) + let d9 = (d1.AddHours 2).AddSeconds(-window' / 2.) + + printfn $"d1 ({d1}) ~= d1 ({d1}): {roughlyEquals d1 d1 window freq}" + printfn $"d1 ({d1}) ~= d2 ({d2}): {roughlyEquals d1 d2 window freq}" + printfn $"d1 ({d1}) ~= d3 ({d3}): {roughlyEquals d1 d3 window freq}" + printfn $"d1 ({d1}) ~= d4 ({d4}): {roughlyEquals d1 d4 window freq}" + printfn $"d1 ({d1}) ~= d5 ({d5}): {roughlyEquals d1 d5 window freq}" + + printfn $"d1 ({d1}) ~= d6 ({d6}): {roughlyEquals d1 d6 window freq}" + printfn $"d1 ({d1}) ~= d7 ({d7}): {roughlyEquals d1 d7 window freq}" + printfn $"d1 ({d1}) ~= d8 ({d8}): {roughlyEquals d1 d8 window freq}" + printfn $"d1 ({d1}) ~= d9 ({d9}): {roughlyEquals d1 d9 window freq}" + +// The example displays output similar to the following: +// d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True +// d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False +// d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False +// d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True +// d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True +// d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False +// d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False +// d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True +// d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True +// +testRoughlyEquals () \ No newline at end of file diff --git a/snippets/fsharp/System/DateTime/Overview/Instantiation.fs b/snippets/fsharp/System/DateTime/Overview/Instantiation.fs new file mode 100644 index 00000000000..b2414a9b60d --- /dev/null +++ b/snippets/fsharp/System/DateTime/Overview/Instantiation.fs @@ -0,0 +1,42 @@ +module Instantiation + +open System + +let instantiateWithConstructor () = + // + let date1 = DateTime(2008, 5, 1, 8, 30, 52) + printfn $"{date1}" + // + +let instantiateWithReturnValue () = + // + let date1 = DateTime.Now + let date2 = DateTime.UtcNow + let date3 = DateTime.Today + // + () + +let instantiateFromString () = + // + let dateString = "5/1/2008 8:30:52 AM" + let date1 = DateTime.Parse(dateString, System.Globalization.CultureInfo.InvariantCulture) + let iso8601String = "20080501T08:30:52Z" + let dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", System.Globalization.CultureInfo.InvariantCulture) + // + () + +let instantiateUsingDftCtor () = + // + let dat1 = DateTime() + + // The following method call displays 1/1/0001 12:00:00 AM. + printfn $"{dat1.ToString System.Globalization.CultureInfo.InvariantCulture}" + + // The following method call displays True. + printfn $"{dat1.Equals DateTime.MinValue}" + // + +instantiateWithConstructor () +instantiateWithReturnValue () +instantiateFromString () +instantiateUsingDftCtor () \ No newline at end of file diff --git a/snippets/fsharp/System/DateTime/Overview/Parsing.fs b/snippets/fsharp/System/DateTime/Overview/Parsing.fs new file mode 100644 index 00000000000..65ea361045d --- /dev/null +++ b/snippets/fsharp/System/DateTime/Overview/Parsing.fs @@ -0,0 +1,64 @@ +module Parsing + +open System + +let parseStandardFormats () = + // + System.Threading.Thread.CurrentThread.CurrentCulture <- + System.Globalization.CultureInfo.CreateSpecificCulture "en-GB" + + let date1 = DateTime(2013, 6, 1, 12, 32, 30) + let badFormats = ResizeArray() + + printfn "%-37s %-19s\n" "Date String" "Date" + for dateString in date1.GetDateTimeFormats() do + match DateTime.TryParse dateString with + | true, parsedDate -> + printfn $"%-37s{dateString} %-19O{parsedDate}\n" + | _ -> + badFormats.Add dateString + + // Display strings that could not be parsed. + if badFormats.Count > 0 then + printfn "\nStrings that could not be parsed: " + for badFormat in badFormats do + printfn $" {badFormat}" + // Press "Run" to see the output. + // + +let parseCustomFormats () = + // + let formats = [| "yyyyMMdd"; "HHmmss" |] + let dateStrings = + [ "20130816"; "20131608"; " 20130816 " + "115216"; "521116"; " 115216 " ] + + for dateString in dateStrings do + match DateTime.TryParseExact(dateString, formats, null, + System.Globalization.DateTimeStyles.AllowWhiteSpaces ||| + System.Globalization.DateTimeStyles.AdjustToUniversal) with + | true, parsedDate -> + printfn $"{dateString} --> {parsedDate:g}" + | _ -> + printfn $"Cannot convert {dateString}" + + // The example displays the following output: + // 20130816 --> 8/16/2013 12:00 AM + // Cannot convert 20131608 + // 20130816 --> 8/16/2013 12:00 AM + // 115216 --> 4/22/2013 11:52 AM + // Cannot convert 521116 + // 115216 --> 4/22/2013 11:52 AM + // + +let parseISO8601 () = + // + let iso8601String = "20080501T08:30:52Z" + let dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", System.Globalization.CultureInfo.InvariantCulture) + + printfn $"{iso8601String} --> {dateISO8602:g}" + // + +parseStandardFormats () +parseCustomFormats () +parseISO8601 () \ No newline at end of file diff --git a/snippets/fsharp/System/DateTime/Overview/Persistence.fs b/snippets/fsharp/System/DateTime/Overview/Persistence.fs new file mode 100644 index 00000000000..b42f0e2a466 --- /dev/null +++ b/snippets/fsharp/System/DateTime/Overview/Persistence.fs @@ -0,0 +1,284 @@ +module Persistence + +open System +open System.Collections.Generic +open System.Globalization +open System.IO +open System.Runtime.Serialization +open System.Runtime.Serialization.Formatters.Binary +open System.Threading +open System.Xml.Serialization +open DateTimeExtensions + +let filenameTxt = @".\BadDates.txt" + +// +let saveLocalDatesAsString () = + let dates = + [ DateTime(2014, 6, 14, 6, 32, 0) + DateTime(2014, 7, 10, 23, 49, 0) + DateTime(2015, 1, 10, 1, 16, 0) + DateTime(2014, 12, 20, 21, 45, 0) + DateTime(2014, 6, 2, 15, 14, 0) ] + + printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}" + printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:" + + let output = + [ for date in dates do + printfn $"{date}" + string date ] + |> String.concat "|" + + use sw = new StreamWriter(filenameTxt) + sw.Write output + printfn "Saved dates..." + +let restoreLocalDatesFromString () = + TimeZoneInfo.ClearCachedData() + printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}" + Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB" + + use sr = new StreamReader(filenameTxt) + let inputValues = + sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries) + + printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:" + + for inputValue in inputValues do + match DateTime.TryParse inputValue with + | true, dateValue -> + printfn $"'{inputValue}' --> {dateValue:f}" + | _ -> + printfn $"Cannot parse '{inputValue}'" + + printfn "Restored dates..." + +let persistAsLocalStrings () = + saveLocalDatesAsString () + restoreLocalDatesFromString () + +// When saved on an en-US system, the example displays the following output: +// Current Time Zone: (UTC-08:00) Pacific Time (US & Canada) +// The dates on an en-US system: +// Saturday, June 14, 2014 6:32 AM +// Thursday, July 10, 2014 11:49 PM +// Saturday, January 10, 2015 1:16 AM +// Saturday, December 20, 2014 9:45 PM +// Monday, June 02, 2014 3:14 PM +// Saved dates... +// +// When restored on an en-GB system, the example displays the following output: +// Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London +// The dates on an en-GB system: +// Cannot parse //6/14/2014 6:32:00 AM// +// //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49 +// //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16 +// Cannot parse //12/20/2014 9:45:00 PM// +// //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14 +// Restored dates... +// + +// +let saveDatesAsInvariantStrings () = + let dates = + [ DateTime(2014, 6, 14, 6, 32, 0) + DateTime(2014, 7, 10, 23, 49, 0) + DateTime(2015, 1, 10, 1, 16, 0) + DateTime(2014, 12, 20, 21, 45, 0) + DateTime(2014, 6, 2, 15, 14, 0) ] + + printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}" + printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:" + + let output = + [ for date in dates do + printfn $"{date:f}" + date.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture) ] + |> String.concat "|" + + use sw = new StreamWriter(filenameTxt) + sw.Write output + printfn "Saved dates..." + +let restoreDatesAsInvariantStrings () = + TimeZoneInfo.ClearCachedData() + printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}" + Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB" + + use sr = new StreamReader(filenameTxt) + let inputValues = + sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries) + + printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:" + + for inputValue in inputValues do + match DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind) with + | true, dateValue -> + printfn $"'{inputValue}' --> {dateValue.ToLocalTime():f}" + | _ -> + printfn $"Cannot parse '{inputValue}'" + + printfn "Restored dates..." + +let persistAsInvariantStrings () = + saveDatesAsInvariantStrings () + restoreDatesAsInvariantStrings () + +// When saved on an en-US system, the example displays the following output: +// Current Time Zone: (UTC-08:00) Pacific Time (US & Canada) +// The dates on an en-US system: +// Saturday, June 14, 2014 6:32 AM +// Thursday, July 10, 2014 11:49 PM +// Saturday, January 10, 2015 1:16 AM +// Saturday, December 20, 2014 9:45 PM +// Monday, June 02, 2014 3:14 PM +// Saved dates... +// +// When restored on an en-GB system, the example displays the following output: +// Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London +// The dates on an en-GB system: +// '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32 +// '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49 +// '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16 +// '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45 +// '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14 +// Restored dates... +// + +let filenameInts = @".\IntDates.bin" + +// +let saveDatesAsInts () = + let dates = + [ DateTime(2014, 6, 14, 6, 32, 0) + DateTime(2014, 7, 10, 23, 49, 0) + DateTime(2015, 1, 10, 1, 16, 0) + DateTime(2014, 12, 20, 21, 45, 0) + DateTime(2014, 6, 2, 15, 14, 0) ] + + printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}" + printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:" + let ticks = + [| for date in dates do + printfn $"{date:f}" + date.ToUniversalTime().Ticks |] + use fs = new FileStream(filenameInts, FileMode.Create) + use bw = new BinaryWriter(fs) + bw.Write ticks.Length + + for tick in ticks do + bw.Write tick + + printfn "Saved dates..." + +let restoreDatesAsInts () = + TimeZoneInfo.ClearCachedData() + printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}" + Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB" + use fs = new FileStream(filenameInts, FileMode.Open) + use br = new BinaryReader(fs) + + try + let items = br.ReadInt32() + let dates = + [| for _ in 0..items do + let ticks = br.ReadInt64() + DateTime(ticks).ToLocalTime() |] + + printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:" + for value in dates do + printfn $"{value:f}" + with + | :? EndOfStreamException -> + printfn "File corruption detected. Unable to restore data..." + | :? IOException -> + printfn "Unspecified I/O error. Unable to restore data..." + // Thrown during array initialization. + | :? OutOfMemoryException -> + printfn"File corruption detected. Unable to restore data..." + + printfn "Restored dates..." + +let persistAsIntegers () = + saveDatesAsInts () + restoreDatesAsInts () + +// When saved on an en-US system, the example displays the following output: +// Current Time Zone: (UTC-08:00) Pacific Time (US & Canada) +// The dates on an en-US system: +// Saturday, June 14, 2014 6:32 AM +// Thursday, July 10, 2014 11:49 PM +// Saturday, January 10, 2015 1:16 AM +// Saturday, December 20, 2014 9:45 PM +// Monday, June 02, 2014 3:14 PM +// Saved dates... +// +// When restored on an en-GB system, the example displays the following output: +// Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London +// The dates on an en-GB system: +// 14 June 2014 14:32 +// 11 July 2014 07:49 +// 10 January 2015 09:16 +// 21 December 2014 05:45 +// 02 June 2014 23:14 +// Restored dates... +// + +let filenameXml = @".\LeapYears.xml" + +// +let persistAsXML () = + // Serialize the data. + let leapYears = + [| for year in 2000..4..2100 do + if DateTime.IsLeapYear year then + DateTime(year, 2, 29) |] + + let serializer = XmlSerializer(leapYears.GetType()) + use sw = new StreamWriter(filenameXml) + + try + serializer.Serialize(sw, leapYears) + with :? InvalidOperationException as e -> + printfn $"{e.InnerException.Message}" + + // Deserialize the data. + use fs = new FileStream(filenameXml, FileMode.Open) + + let deserializedDates = serializer.Deserialize fs :?> DateTime [] + + // Display the dates. + printfn $"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:" + + let mutable nItems = 0 + for dat in deserializedDates do + printf $" {dat:d} " + nItems <- nItems + 1 + if nItems % 5 = 0 then + printfn "" + +// The example displays the following output: +// Leap year days from 2000-2100 on an en-GB system: +// 29/02/2000 29/02/2004 29/02/2008 29/02/2012 29/02/2016 +// 29/02/2020 29/02/2024 29/02/2028 29/02/2032 29/02/2036 +// 29/02/2040 29/02/2044 29/02/2048 29/02/2052 29/02/2056 +// 29/02/2060 29/02/2064 29/02/2068 29/02/2072 29/02/2076 +// 29/02/2080 29/02/2084 29/02/2088 29/02/2092 29/02/2096 +// + +let filenameBin = @".\Dates.bin" + +File.Delete filenameTxt +persistAsLocalStrings () +File.Delete filenameTxt +persistAsInvariantStrings () +File.Delete filenameTxt + +File.Delete filenameInts +persistAsIntegers () +File.Delete filenameInts + +File.Delete filenameXml +persistAsXML () +File.Delete filenameXml diff --git a/snippets/fsharp/System/DateTime/Overview/Resolution.fs b/snippets/fsharp/System/DateTime/Overview/Resolution.fs new file mode 100644 index 00000000000..0edf94059e0 --- /dev/null +++ b/snippets/fsharp/System/DateTime/Overview/Resolution.fs @@ -0,0 +1,19 @@ +module Resolution + +open System + +let demonstrateResolution () = + // + let mutable output = "" + for i = 0 to 20 do + output <- output + $"{DateTime.Now.Millisecond}\n" + // Introduce a delay loop. + for _ = 0 to 1000 do () + + if i = 10 then + output <- output + "Thread.Sleep called...\n" + System.Threading.Thread.Sleep 5 + + printfn $"{output}" + // Press "Run" to see the output. + // \ No newline at end of file diff --git a/snippets/fsharp/System/DateTime/Overview/StringFormat.fs b/snippets/fsharp/System/DateTime/Overview/StringFormat.fs new file mode 100644 index 00000000000..928aaee4981 --- /dev/null +++ b/snippets/fsharp/System/DateTime/Overview/StringFormat.fs @@ -0,0 +1,44 @@ +module StringFormat + +open System + +let showDefaultToString () = + // + let date1 = DateTime(2008, 3, 1, 7, 0, 0) + printfn $"{date1.ToString()}" + // For en-US culture, displays 3/1/2008 7:00:00 AM + // + +let showCultureSpecificToString () = + // + let date1 = DateTime(2008, 3, 1, 7, 0, 0) + printfn $"""{date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture "fr-FR")}""" + // Displays 01/03/2008 07:00:00 + // + +let showDefaultFullDateAndTime () = + // + let date1 = DateTime(2008, 3, 1, 7, 0, 0) + printfn $"""{date1.ToString "F"}""" + // Displays Saturday, March 01, 2008 7:00:00 AM + // + +let showCultureSpecificFullDateAndTime () = + // + let date1 = DateTime(2008, 3, 1, 7, 0, 0) + printfn $"""{date1.ToString("F", new System.Globalization.CultureInfo "fr-FR")}""" + // Displays samedi 1 mars 2008 07:00:00 + // + +let showIso8601Format () = + // + let date1 = DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc) + printfn $"""{date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture)}""" + // Displays 2008-03-01T07:00:00+00:00 + // + +showDefaultToString () +showCultureSpecificToString () +showDefaultFullDateAndTime () +showCultureSpecificFullDateAndTime () +showIso8601Format () \ No newline at end of file diff --git a/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs b/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs new file mode 100644 index 00000000000..9ed094ca96a --- /dev/null +++ b/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs @@ -0,0 +1,101 @@ +module openClosedOver + +// All four permutations of instance/static with open/closed. +// +// +open System +open System.Reflection + +// A sample class with an instance method and a static method. +type C(id) = + member _.M1(s) = + printfn $"Instance method M1 on C: id = %i{id}, s = %s{s}" + + static member M2(s) = + printfn $"Static method M2 on C: s = %s{s}" + +// Declare three delegate types for demonstrating the combinations +// of static versus instance methods and open versus closed +// delegates. +type D1 = delegate of C * string -> unit +type D2 = delegate of string -> unit +type D3 = delegate of unit -> unit + +let c1 = C 42 + +// Get a MethodInfo for each method. +// +let mi1 = typeof.GetMethod("M1", BindingFlags.Public ||| BindingFlags.Instance) +let mi2 = typeof.GetMethod("M2", BindingFlags.Public ||| BindingFlags.Static) + +printfn "\nAn instance method closed over C." + +// In this case, the delegate and the +// method must have the same list of argument types use +// delegate type D2 with instance method M1. +let test = Delegate.CreateDelegate(typeof, c1, mi1, false) + +// Because false was specified for throwOnBindFailure +// in the call to CreateDelegate, the variable 'test' +// contains null if the method fails to bind (for +// example, if mi1 happened to represent a method of +// some class other than C). +if test <> null then + let d2 = test :?> D2 + + // The same instance of C is used every time the + // delegate is invoked. + d2.Invoke "Hello, World!" + d2.Invoke "Hi, Mom!" + +printfn "\nAn open instance method." + +// In this case, the delegate has one more +// argument than the instance method this argument comes +// at the beginning, and represents the hidden instance +// argument of the instance method. Use delegate type D1 +// with instance method M1. +let d1 = Delegate.CreateDelegate(typeof, null, mi1) :?> D1 + +// An instance of C must be passed in each time the +// delegate is invoked. +d1.Invoke(c1, "Hello, World!") +d1.Invoke(C 5280, "Hi, Mom!") + +printfn "\nAn open static method." +// In this case, the delegate and the method must +// have the same list of argument types use delegate type +// D2 with static method M2. +let d2 = Delegate.CreateDelegate(typeof, null, mi2) :?> D2 + +// No instances of C are involved, because this is a static +// method. +d2.Invoke "Hello, World!" +d2.Invoke "Hi, Mom!" + +printfn "\nA static method closed over the first argument (String)." +// The delegate must omit the first argument of the method. +// A string is passed as the firstArgument parameter, and +// the delegate is bound to this string. Use delegate type +// D3 with static method M2. +let d3 = Delegate.CreateDelegate(typeof, "Hello, World!", mi2) :?> D3 + +// Each time the delegate is invoked, the same string is used. +d3.Invoke() + +// This code example produces the following output: +// An instance method closed over C. +// Instance method M1 on C: id = 42, s = Hello, World! +// Instance method M1 on C: id = 42, s = Hi, Mom! +// +// An open instance method. +// Instance method M1 on C: id = 42, s = Hello, World! +// Instance method M1 on C: id = 5280, s = Hi, Mom! +// +// An open static method. +// Static method M2 on C: s = Hello, World! +// Static method M2 on C: s = Hi, Mom! +// +// A static method closed over the first argument (String). +// Static method M2 on C: s = Hello, World! +// \ No newline at end of file diff --git a/snippets/fsharp/System/Delegate/CreateDelegate/source.fs b/snippets/fsharp/System/Delegate/CreateDelegate/source.fs new file mode 100644 index 00000000000..529381000b4 --- /dev/null +++ b/snippets/fsharp/System/Delegate/CreateDelegate/source.fs @@ -0,0 +1,126 @@ +module source + +// Showing all the things D(A) can bind to. +// +open System + +// Declare two sample classes, C and F. Class C has an ID +// property so instances can be identified. +type C(id) = + member _.ID = id + + member _.M1(c: C) = + printfn $"Instance method M1(C c) on C: this.id = {id}, c.ID = {c.ID}" + + member _.M2() = + printfn $"Instance method M2() on C: this.id = {id}" + + static member M3(c: C) = + printfn $"Static method M3(C c) on C: c.ID = {c.ID}" + + static member M4(c1: C, c2: C) = + printfn $"Static method M4(C c1, C c2) on C: c1.ID = {c1.ID}, c2.ID = {c2.ID}" + +// Declare a delegate type. The object of this code example +// is to show all the methods this delegate can bind to. +type D = delegate of C -> unit + + +type F() = + member _.M1(c: C) = + printfn $"Instance method M1(C c) on F: c.ID = {c.ID}" + + member _.M3(c: C) = + printfn $"Static method M3(C c) on F: c.ID = {c.ID}" + + member _.M4(f: F, c: C) = + printfn $"Static method M4(F f, C c) on F: c.ID = {c.ID}" + +[] +let main _ = + let c1 = C 42 + let c2 = C 1491 + let f1 = F() + + // Instance method with one argument of type C. + let cmi1 = typeof.GetMethod "M1" + // Instance method with no arguments. + let cmi2 = typeof.GetMethod "M2" + // Static method with one argument of type C. + let cmi3 = typeof.GetMethod "M3" + // Static method with two arguments of type C. + let cmi4 = typeof.GetMethod "M4" + + // Instance method with one argument of type C. + let fmi1 = typeof.GetMethod "M1" + // Static method with one argument of type C. + let fmi3 = typeof.GetMethod "M3" + // Static method with an argument of type F and an argument + // of type C. + let fmi4 = typeof.GetMethod "M4" + + printfn "\nAn instance method on any type, with an argument of type C." + // D can represent any instance method that exactly matches its + // signature. Methods on C and F are shown here. + let d = Delegate.CreateDelegate(typeof, c1, cmi1) :?> D + d.Invoke c2 + let d = Delegate.CreateDelegate(typeof, f1, fmi1) :?> D + d.Invoke c2 + + Console.WriteLine("\nAn instance method on C with no arguments.") + // D can represent an instance method on C that has no arguments + // in this case, the argument of D represents the hidden first + // argument of any instance method. The delegate acts like a + // static method, and an instance of C must be passed each time + // it is invoked. + let d = Delegate.CreateDelegate(typeof, null, cmi2) :?> D + d.Invoke c1 + + printfn "\nA static method on any type, with an argument of type C." + // D can represent any static method with the same signature. + // Methods on F and C are shown here. + let d = Delegate.CreateDelegate(typeof, null, cmi3) :?> D + d.Invoke c1 + let d = Delegate.CreateDelegate(typeof, null, fmi3) :?> D + d.Invoke c1 + + printfn "\nA static method on any type, with an argument of" + printfn " that type and an argument of type C." + // D can represent any static method with one argument of the + // type the method belongs and a second argument of type C. + // In this case, the method is closed over the instance of + // supplied for the its first argument, and acts like an instance + // method. Methods on F and C are shown here. + let d = Delegate.CreateDelegate(typeof, c1, cmi4) :?> D + d.Invoke c2 + let test = + Delegate.CreateDelegate(typeof, f1, fmi4, false) + + // This final example specifies false for throwOnBindFailure + // in the call to CreateDelegate, so the variable 'test' + // contains Nothing if the method fails to bind (for + // example, if fmi4 happened to represent a method of + // some class other than F). + match test with + | :? D as d -> + d.Invoke c2 + | _ -> () + 0 + +// This code example produces the following output: +// An instance method on any type, with an argument of type C. +// Instance method M1(C c) on C: this.id = 42, c.ID = 1491 +// Instance method M1(C c) on F: c.ID = 1491 +// +// An instance method on C with no arguments. +// Instance method M2() on C: this.id = 42 +// +// A static method on any type, with an argument of type C. +// Static method M3(C c) on C: c.ID = 42 +// Static method M3(C c) on F: c.ID = 42 +// +// A static method on any type, with an argument of +// that type and an argument of type C. +// Static method M4(C c1, C c2) on C: c1.ID = 42, c2.ID = 1491 +// Static method M4(F f, C c) on F: c.ID = 1491 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs b/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs new file mode 100644 index 00000000000..fc02c8ebe28 --- /dev/null +++ b/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs @@ -0,0 +1,45 @@ +module source1 + +// +open System +open System.Reflection + +// Define two classes to use in the demonstration, a base class and +// a class that derives from it. +type Base() = class end + +type Derived() = + inherit Base() + + // Define a static method to use in the demonstration. The method + // takes an instance of Base and returns an instance of Derived. + // For the purposes of the demonstration, it is not necessary for + // the method to do anything useful. + static member MyMethod(arg: Base) = + Derived() + +// Define a delegate that takes an instance of Derived and returns an +// instance of Base. +type Example = delegate of Derived -> Base + +// The binding flags needed to retrieve MyMethod. +let flags = BindingFlags.Public ||| BindingFlags.Static + +// Get a MethodInfo that represents MyMethod. +let minfo = typeof.GetMethod("MyMethod", flags) + +// Demonstrate contravariance of parameter types and covariance +// of return types by using the delegate Example to represent +// MyMethod. The delegate binds to the method because the +// parameter of the delegate is more restrictive than the +// parameter of the method (that is, the delegate accepts an +// instance of Derived, which can always be safely passed to +// a parameter of type Base), and the return type of MyMethod +// is more restrictive than the return type of Example (that +// is, the method returns an instance of Derived, which can +// always be safely cast to type Base). +let ex = Delegate.CreateDelegate(typeof, minfo) :?> Example + +// Execute MyMethod using the delegate Example. +let b = Derived() |> ex.Invoke +// \ No newline at end of file diff --git a/snippets/fsharp/System/Double/CompareTo/compareto2.fs b/snippets/fsharp/System/Double/CompareTo/compareto2.fs new file mode 100644 index 00000000000..7da23de2bac --- /dev/null +++ b/snippets/fsharp/System/Double/CompareTo/compareto2.fs @@ -0,0 +1,12 @@ +module compareto2 + +// +let value1 = 6.185 +let value2 = value1 * 0.1 / 0.1 +printfn $"Comparing {value1} and {value2}: {value1.CompareTo value2}\n" +printfn $"Comparing {value1:R} and {value2:R}: {value1.CompareTo value2}" +// The example displays the following output: +// Comparing 6.185 and 6.185: -1 +// +// Comparing 6.185 and 6.1850000000000005: -1 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Double/CompareTo/compareto3.fs b/snippets/fsharp/System/Double/CompareTo/compareto3.fs new file mode 100644 index 00000000000..62f5503a469 --- /dev/null +++ b/snippets/fsharp/System/Double/CompareTo/compareto3.fs @@ -0,0 +1,12 @@ +module compareto3 + +// +let value1 = 6.185 +let value2 = value1 * 0.1 / 0.1 |> box +printfn $"Comparing {value1} and {value2}: {value1.CompareTo value2}\n" +printfn $"Comparing {value1:R} and {value2:R}: {value1.CompareTo value2}" +// The example displays the following output: +// Comparing 6.185 and 6.185: -1 +// +// Comparing 6.185 and 6.1850000000000005: -1 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Double/Epsilon/epsilon.fs b/snippets/fsharp/System/Double/Epsilon/epsilon.fs new file mode 100644 index 00000000000..650b9d3ae6e --- /dev/null +++ b/snippets/fsharp/System/Double/Epsilon/epsilon.fs @@ -0,0 +1,17 @@ +module epsilon + +// +open System + +let values = [| 0.; Double.Epsilon; Double.Epsilon * 0.5 |] + +for i = 0 to values.Length - 2 do + for i2 = i + 1 to values.Length - 1 do + printfn $"{values[i]:r} = {values[i2]:r}: {values[i].Equals values[i2]}" + printfn "" +// The example displays the following output: +// 0 = 4.94065645841247E-324: False +// 0 = 0: True +// +// 4.94065645841247E-324 = 0: False +// \ No newline at end of file diff --git a/snippets/fsharp/System/Double/Epsilon/epsilon1.fs b/snippets/fsharp/System/Double/Epsilon/epsilon1.fs new file mode 100644 index 00000000000..8126fb46251 --- /dev/null +++ b/snippets/fsharp/System/Double/Epsilon/epsilon1.fs @@ -0,0 +1,46 @@ +module epsilon1 + +// +open System + +let getComponentParts (value: double) = + let result = $"{value:R}: " + let indent = result.Length + + // Convert the double to an 8-byte array. + let bytes = BitConverter.GetBytes value + // Get the sign bit (byte 7, bit 7). + let result = result + $"""Sign: {if (bytes[7] &&& 0x80uy) = 0x80uy then "1 (-)" else "0 (+)"}\n""" + + // Get the exponent (byte 6 bits 4-7 to byte 7, bits 0-6) + let exponent = (bytes[7] &&& 0x07Fuy) <<< 4 + let exponent = exponent ||| ((bytes[6] &&& 0xF0uy) >>> 4) + let adjustment = if exponent <> 0uy then 1022 else 1023 + let result = result + $"{String(' ', indent)}Exponent: 0x{int exponent - adjustment:X4} ({int exponent - adjustment})\n" + + // Get the significand (bits 0-51) + let significand = (bytes[6] &&& 0x0Fuy) <<< 48 + let significand = significand ||| byte (int64 bytes[5] <<< 40) + let significand = significand ||| byte (int64 bytes[4] <<< 32) + let significand = significand ||| byte (int64 bytes[3] <<< 24) + let significand = significand ||| byte (int64 bytes[2] <<< 16) + let significand = significand ||| byte (int64 bytes[1] <<< 8) + let significand = significand ||| bytes[0] + result + $"{String(' ', indent)}Mantissa: 0x{significand:X13}\n" + +let values = [| 0.; Double.Epsilon |] +for value in values do + printfn $"{getComponentParts value}" + printfn "" + + +// // The example displays the following output: +// 0: Sign: 0 (+) +// Exponent: 0xFFFFFC02 (-1022) +// Mantissa: 0x0000000000000 +// +// +// 4.94065645841247E-324: Sign: 0 (+) +// Exponent: 0xFFFFFC02 (-1022) +// Mantissa: 0x0000000000001 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Double/Equals/equalsabs1.fs b/snippets/fsharp/System/Double/Equals/equalsabs1.fs new file mode 100644 index 00000000000..59f4047a639 --- /dev/null +++ b/snippets/fsharp/System/Double/Equals/equalsabs1.fs @@ -0,0 +1,28 @@ +module equalsabs + +// +open System + +let hasMinimalDifference (value1: double) (value2: double) (units: int) = + let lValue1 = BitConverter.DoubleToInt64Bits value1 + let lValue2 = BitConverter.DoubleToInt64Bits value2 + + // If the signs are different, return false except for +0 and -0. + if (lValue1 >>> 63) <> (lValue2 >>> 63) then + value1 = value2 + else + let diff = abs (lValue1 - lValue2) + + diff <= int64 units + +let value1 = 0.1 * 10. +let mutable value2 = 0. +for _ = 0 to 9 do + value2 <- value2 + 0.1 + +printfn $"{value1:R} = {value2:R}: {hasMinimalDifference value1 value2 1}" + + +// The example displays the following output: +// 1 = 0.99999999999999989: True +// \ No newline at end of file diff --git a/snippets/visualbasic/System/AppContext/Overview/V1/Example4.vb b/snippets/visualbasic/System/AppContext/Overview/V1/Example4.vb new file mode 100644 index 00000000000..2dcb806cc7f --- /dev/null +++ b/snippets/visualbasic/System/AppContext/Overview/V1/Example4.vb @@ -0,0 +1,32 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Reflection + + + +Public Class StringLibrary + Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer + Return fullString.IndexOf(substr, StringComparison.Ordinal) + End Function +End Class +' + +' +Public Module Example4 + Public Sub Main() + Dim value As String = "The archaeologist" + Dim substring As String = "archæ" + Dim position As Integer = StringLibrary.SubstringStartsAt(value, substring) + If position >= 0 Then + Console.WriteLine("'{0}' found in '{1}' starting at position {2}", + substring, value, position) + Else + Console.WriteLine("'{0}' not found in '{1}'", substring, value) + End If + End Sub +End Module +' The example displays the following output: +' 'archæ' not found in 'The archaeologist' +' diff --git a/snippets/visualbasic/System/AppContext/Overview/V1/Project.vbproj b/snippets/visualbasic/System/AppContext/Overview/V1/Project.vbproj new file mode 100644 index 00000000000..369b05a893e --- /dev/null +++ b/snippets/visualbasic/System/AppContext/Overview/V1/Project.vbproj @@ -0,0 +1,9 @@ + + + + Library + net10.0 + false + + + diff --git a/snippets/visualbasic/System/AppContext/Overview/V2/Example6.vb b/snippets/visualbasic/System/AppContext/Overview/V2/Example6.vb new file mode 100644 index 00000000000..26f0a4a5ed8 --- /dev/null +++ b/snippets/visualbasic/System/AppContext/Overview/V2/Example6.vb @@ -0,0 +1,32 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Reflection + + + +Public Class StringLibrary + Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer + Return fullString.IndexOf(substr, StringComparison.CurrentCulture) + End Function +End Class +' + +' +Public Module Example6 + Public Sub Main() + Dim value As String = "The archaeologist" + Dim substring As String = "archæ" + Dim position As Integer = StringLibrary.SubstringStartsAt(value, substring) + If position >= 0 Then + Console.WriteLine("'{0}' found in '{1}' starting at position {2}", + substring, value, position) + Else + Console.WriteLine("'{0}' not found in '{1}'", substring, value) + End If + End Sub +End Module +' The example displays the following output: +' 'archæ' found in 'The archaeologist' starting at position 4 +' diff --git a/snippets/visualbasic/System/AppContext/Overview/V2/Project.vbproj b/snippets/visualbasic/System/AppContext/Overview/V2/Project.vbproj new file mode 100644 index 00000000000..369b05a893e --- /dev/null +++ b/snippets/visualbasic/System/AppContext/Overview/V2/Project.vbproj @@ -0,0 +1,9 @@ + + + + Library + net10.0 + false + + + diff --git a/snippets/visualbasic/System/AppContext/Overview/V3/Example8.vb b/snippets/visualbasic/System/AppContext/Overview/V3/Example8.vb new file mode 100644 index 00000000000..eb221282b6a --- /dev/null +++ b/snippets/visualbasic/System/AppContext/Overview/V3/Example8.vb @@ -0,0 +1,37 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Reflection + + + +Public Class StringLibrary + Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer + Dim flag As Boolean + If AppContext.TryGetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison", flag) AndAlso flag = True Then + Return fullString.IndexOf(substr, StringComparison.Ordinal) + Else + Return fullString.IndexOf(substr, StringComparison.CurrentCulture) + End If + End Function +End Class +' + +' +Public Module Example8 + Public Sub Main() + Dim value As String = "The archaeologist" + Dim substring As String = "archæ" + Dim position As Integer = StringLibrary.SubstringStartsAt(value, substring) + If position >= 0 Then + Console.WriteLine("'{0}' found in '{1}' starting at position {2}", + substring, value, position) + Else + Console.WriteLine("'{0}' not found in '{1}'", substring, value) + End If + End Sub +End Module +' The example displays the following output: +' 'archæ' not found in 'The archaeologist' +' diff --git a/snippets/visualbasic/System/AppContext/Overview/V3/Project.vbproj b/snippets/visualbasic/System/AppContext/Overview/V3/Project.vbproj new file mode 100644 index 00000000000..369b05a893e --- /dev/null +++ b/snippets/visualbasic/System/AppContext/Overview/V3/Project.vbproj @@ -0,0 +1,9 @@ + + + + Library + net10.0 + false + + + diff --git a/snippets/visualbasic/System/Boolean/Overview/Project.vbproj b/snippets/visualbasic/System/Boolean/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Boolean/Overview/binary1.vb b/snippets/visualbasic/System/Boolean/Overview/binary1.vb new file mode 100644 index 00000000000..1f05bc46a85 --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/binary1.vb @@ -0,0 +1,34 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example1 + Public Sub Main() + Dim flags() As Boolean = {True, False} + For Each flag In flags + ' Get binary representation of flag. + Dim value As Byte = BitConverter.GetBytes(flag)(0) + Console.WriteLine("Original value: {0}", flag) + Console.WriteLine("Binary value: {0} ({1})", value, + GetBinaryString(value)) + ' Restore the flag from its binary representation. + Dim newFlag As Boolean = BitConverter.ToBoolean({value}, 0) + Console.WriteLine("Restored value: {0}", newFlag) + Console.WriteLine() + Next + End Sub + + Private Function GetBinaryString(value As Byte) As String + Dim retVal As String = Convert.ToString(value, 2) + Return New String("0"c, 8 - retVal.Length) + retVal + End Function +End Module +' The example displays the following output: +' Original value: True +' Binary value: 1 (00000001) +' Restored value: True +' +' Original value: False +' Binary value: 0 (00000000) +' Restored value: False +' diff --git a/snippets/visualbasic/System/Boolean/Overview/conversion1.vb b/snippets/visualbasic/System/Boolean/Overview/conversion1.vb new file mode 100644 index 00000000000..9f3f7250449 --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/conversion1.vb @@ -0,0 +1,31 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example2 + Public Sub Main() + Dim byteValue As Byte = 12 + Console.WriteLine(Convert.ToBoolean(byteValue)) + Dim byteValue2 As Byte = 0 + Console.WriteLine(Convert.ToBoolean(byteValue2)) + Dim intValue As Integer = -16345 + Console.WriteLine(Convert.ToBoolean(intValue)) + Dim longValue As Long = 945 + Console.WriteLine(Convert.ToBoolean(longValue)) + Dim sbyteValue As SByte = -12 + Console.WriteLine(Convert.ToBoolean(sbyteValue)) + Dim dblValue As Double = 0 + Console.WriteLine(Convert.ToBoolean(dblValue)) + Dim sngValue As Single = 0.0001 + Console.WriteLine(Convert.ToBoolean(sngValue)) + End Sub +End Module +' The example displays the following output: +' True +' False +' True +' True +' True +' False +' True +' diff --git a/snippets/visualbasic/System/Boolean/Overview/conversion3.vb b/snippets/visualbasic/System/Boolean/Overview/conversion3.vb new file mode 100644 index 00000000000..5eee5aa9913 --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/conversion3.vb @@ -0,0 +1,51 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example3 + Public Sub Main() + Dim flag As Boolean = True + + Dim byteValue As Byte + byteValue = Convert.ToByte(flag) + Console.WriteLine("{0} -> {1} ({2})", flag, byteValue, + byteValue.GetType().Name) + byteValue = CByte(flag) + Console.WriteLine("{0} -> {1} ({2})", flag, byteValue, + byteValue.GetType().Name) + + Dim sbyteValue As SByte + sbyteValue = Convert.ToSByte(flag) + Console.WriteLine("{0} -> {1} ({2})", flag, sbyteValue, + sbyteValue.GetType().Name) + sbyteValue = CSByte(flag) + Console.WriteLine("{0} -> {1} ({2})", flag, sbyteValue, + sbyteValue.GetType().Name) + + Dim dblValue As Double + dblValue = Convert.ToDouble(flag) + Console.WriteLine("{0} -> {1} ({2})", flag, dblValue, + dblValue.GetType().Name) + dblValue = CDbl(flag) + Console.WriteLine("{0} -> {1} ({2})", flag, dblValue, + dblValue.GetType().Name) + + Dim intValue As Integer + intValue = Convert.ToInt32(flag) + Console.WriteLine("{0} -> {1} ({2})", flag, intValue, + intValue.GetType().Name) + intValue = CInt(flag) + Console.WriteLine("{0} -> {1} ({2})", flag, intValue, + intValue.GetType().Name) + End Sub +End Module +' The example displays the following output: +' True -> 1 (Byte) +' True -> 255 (Byte) +' True -> 1 (SByte) +' True -> -1 (SByte) +' True -> 1 (Double) +' True -> -1 (Double) +' True -> 1 (Int32) +' True -> -1 (Int32) +' diff --git a/snippets/visualbasic/System/Boolean/Overview/format3.vb b/snippets/visualbasic/System/Boolean/Overview/format3.vb new file mode 100644 index 00000000000..41496eb8cba --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/format3.vb @@ -0,0 +1,78 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Globalization + +Module Example4 + Public Sub Main() + Dim cultureNames() As String = {"", "en-US", "fr-FR", "ru-RU"} + For Each cultureName In cultureNames + Dim value As Boolean = True + Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture(cultureName) + Dim formatter As New BooleanFormatter(culture) + + Dim result As String = String.Format(formatter, "Value for '{0}': {1}", culture.Name, value) + Console.WriteLine(result) + Next + End Sub +End Module + +Public Class BooleanFormatter + Implements ICustomFormatter, IFormatProvider + + Private culture As CultureInfo + + Public Sub New() + Me.New(CultureInfo.CurrentCulture) + End Sub + + Public Sub New(culture As CultureInfo) + Me.culture = culture + End Sub + + Public Function GetFormat(formatType As Type) As Object _ + Implements IFormatProvider.GetFormat + If formatType Is GetType(ICustomFormatter) Then + Return Me + Else + Return Nothing + End If + End Function + + Public Function Format(fmt As String, arg As Object, + formatProvider As IFormatProvider) As String _ + Implements ICustomFormatter.Format + ' Exit if another format provider is used. + If Not formatProvider.Equals(Me) Then Return Nothing + + ' Exit if the type to be formatted is not a Boolean + If Not TypeOf arg Is Boolean Then Return Nothing + + Dim value As Boolean = CBool(arg) + Select culture.Name + Case "en-US" + Return value.ToString() + Case "fr-FR" + If value Then + Return "vrai" + Else + Return "faux" + End If + Case "ru-RU" + If value Then + Return "верно" + Else + Return "неверно" + End If + Case Else + Return value.ToString() + End Select + End Function +End Class +' The example displays the following output: +' Value for '': True +' Value for 'en-US': True +' Value for 'fr-FR': vrai +' Value for 'ru-RU': верно +' diff --git a/snippets/visualbasic/System/Boolean/Overview/operations1.vb b/snippets/visualbasic/System/Boolean/Overview/operations1.vb new file mode 100644 index 00000000000..e7a1126473d --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/operations1.vb @@ -0,0 +1,89 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO +Imports System.Threading + +Module Example5 + Public Sub Main() + ' Initialize flag variables. + Dim isRedirected, isBoth As Boolean + Dim fileName As String = "" + Dim sw As StreamWriter = Nothing + + ' Get any command line arguments. + Dim args() As String = Environment.GetCommandLineArgs() + ' Handle any arguments. + If args.Length > 1 Then + For ctr = 1 To args.Length - 1 + Dim arg As String = args(ctr) + If arg.StartsWith("/") OrElse arg.StartsWith("-") Then + Select Case arg.Substring(1).ToLower() + Case "f" + isRedirected = True + If args.Length < ctr + 2 Then + ShowSyntax("The /f switch must be followed by a filename.") + Exit Sub + End If + fileName = args(ctr + 1) + ctr += 1 + Case "b" + isBoth = True + Case Else + ShowSyntax(String.Format("The {0} switch is not supported", + args(ctr))) + Exit Sub + End Select + End If + Next + End If + + ' If isBoth is True, isRedirected must be True. + If isBoth And Not isRedirected Then + ShowSyntax("The /f switch must be used if /b is used.") + Exit Sub + End If + + ' Handle output. + If isRedirected Then + sw = New StreamWriter(fileName) + If Not isBoth Then + Console.SetOut(sw) + End If + End If + Dim msg As String = String.Format("Application began at {0}", Date.Now) + Console.WriteLine(msg) + If isBoth Then sw.WriteLine(msg) + Thread.Sleep(5000) + msg = String.Format("Application ended normally at {0}", Date.Now) + Console.WriteLine(msg) + If isBoth Then sw.WriteLine(msg) + If isRedirected Then sw.Close() + End Sub + + Private Sub ShowSyntax(errMsg As String) + Console.WriteLine(errMsg) + Console.WriteLine() + Console.WriteLine("Syntax: Example [[/f [/b]]") + Console.WriteLine() + End Sub +End Module +' + + +Public Class Evaluation + Public Sub SomeMethod() + Dim booleanValue As Boolean + + ' + If booleanValue = True Then + ' + End If + + ' + If booleanValue Then + ' + End If + End Sub +End Class diff --git a/snippets/visualbasic/System/Boolean/Overview/operations2.vb b/snippets/visualbasic/System/Boolean/Overview/operations2.vb new file mode 100644 index 00000000000..1ec2daa75bf --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/operations2.vb @@ -0,0 +1,23 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example6 + Public Sub Main() + Dim hasServiceCharges() As Boolean = {True, False} + Dim subtotal As Decimal = 120.62D + Dim shippingCharge As Decimal = 2.5D + Dim serviceCharge As Decimal = 5D + + For Each hasServiceCharge In hasServiceCharges + Dim total As Decimal = subtotal + shippingCharge + + If(hasServiceCharge, serviceCharge, 0) + Console.WriteLine("hasServiceCharge = {1}: The total is {0:C2}.", + total, hasServiceCharge) + Next + End Sub +End Module +' The example displays output like the following: +' hasServiceCharge = True: The total is $128.12. +' hasServiceCharge = False: The total is $123.12. +' diff --git a/snippets/visualbasic/System/Boolean/Overview/parse2.vb b/snippets/visualbasic/System/Boolean/Overview/parse2.vb new file mode 100644 index 00000000000..fdc1d5091c4 --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/parse2.vb @@ -0,0 +1,65 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example7 + Public Sub Main() + Dim values() As String = {Nothing, String.Empty, "True", "False", + "true", "false", " true ", + "TrUe", "fAlSe", "fa lse", "0", + "1", "-1", "string"} + ' Parse strings using the Boolean.Parse method. + For Each value In values + Try + Dim flag As Boolean = Boolean.Parse(value) + Console.WriteLine("'{0}' --> {1}", value, flag) + Catch e As ArgumentException + Console.WriteLine("Cannot parse a null string.") + Catch e As FormatException + Console.WriteLine("Cannot parse '{0}'.", value) + End Try + Next + Console.WriteLine() + ' Parse strings using the Boolean.TryParse method. + For Each value In values + Dim flag As Boolean = False + If Boolean.TryParse(value, flag) Then + Console.WriteLine("'{0}' --> {1}", value, flag) + Else + Console.WriteLine("Cannot parse '{0}'.", value) + End If + Next + End Sub +End Module +' The example displays the following output: +' Cannot parse a null string. +' Cannot parse ''. +' 'True' --> True +' 'False' --> False +' 'true' --> True +' 'false' --> False +' ' true ' --> True +' 'TrUe' --> True +' 'fAlSe' --> False +' Cannot parse 'fa lse'. +' Cannot parse '0'. +' Cannot parse '1'. +' Cannot parse '-1'. +' Cannot parse 'string'. +' +' Unable to parse '' +' Unable to parse '' +' 'True' --> True +' 'False' --> False +' 'true' --> True +' 'false' --> False +' ' true ' --> True +' 'TrUe' --> True +' 'fAlSe' --> False +' Cannot parse 'fa lse'. +' Unable to parse '0' +' Unable to parse '1' +' Unable to parse '-1' +' Unable to parse 'string' +' + diff --git a/snippets/visualbasic/System/Boolean/Overview/parse3.vb b/snippets/visualbasic/System/Boolean/Overview/parse3.vb new file mode 100644 index 00000000000..ccaaf8c8285 --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/parse3.vb @@ -0,0 +1,27 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example8 + Public Sub Main() + Dim values() As String = {"09", "12.6", "0", "-13 "} + For Each value In values + Dim success, result As Boolean + Dim number As Integer + success = Int32.TryParse(value, number) + If success Then + ' The method throws no exceptions. + result = Convert.ToBoolean(number) + Console.WriteLine("Converted '{0}' to {1}", value, result) + Else + Console.WriteLine("Unable to convert '{0}'", value) + End If + Next + End Sub +End Module +' The example displays the following output: +' Converted '09' to True +' Unable to convert '12.6' +' Converted '0' to False +' Converted '-13 ' to True +' diff --git a/snippets/visualbasic/System/Boolean/Overview/tostring1.vb b/snippets/visualbasic/System/Boolean/Overview/tostring1.vb new file mode 100644 index 00000000000..0c3536e307d --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/tostring1.vb @@ -0,0 +1,17 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example9 + Public Sub Main() + Dim raining As Boolean = False + Dim busLate As Boolean = True + + Console.WriteLine("It is raining: {0}", raining) + Console.WriteLine("The bus is late: {0}", busLate) + End Sub +End Module +' The example displays the following output: +' It is raining: False +' The bus is late: True +' diff --git a/snippets/visualbasic/System/Boolean/Overview/tostring2.vb b/snippets/visualbasic/System/Boolean/Overview/tostring2.vb new file mode 100644 index 00000000000..e77645b1a82 --- /dev/null +++ b/snippets/visualbasic/System/Boolean/Overview/tostring2.vb @@ -0,0 +1,19 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example + Public Sub Main() + Dim raining As Boolean = False + Dim busLate As Boolean = True + + Console.WriteLine("It is raining: {0}", + If(raining, "Yes", "No")) + Console.WriteLine("The bus is late: {0}", + If(busLate, "Yes", "No")) + End Sub +End Module +' The example displays the following output: +' It is raining: No +' The bus is late: Yes +' \ No newline at end of file diff --git a/snippets/visualbasic/System/Byte/Overview/Project.vbproj b/snippets/visualbasic/System/Byte/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Byte/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Byte/Overview/bitwise1.vb b/snippets/visualbasic/System/Byte/Overview/bitwise1.vb new file mode 100644 index 00000000000..907dd931e35 --- /dev/null +++ b/snippets/visualbasic/System/Byte/Overview/bitwise1.vb @@ -0,0 +1,25 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Globalization + +Module Example1 + Public Sub Main() + Dim values() As String = {Convert.ToString(12, 16), + Convert.ToString(123, 16), + Convert.ToString(245, 16)} + + Dim mask As Byte = &HFE + For Each value As String In values + Dim byteValue As Byte = Byte.Parse(value, NumberStyles.AllowHexSpecifier) + Console.WriteLine("{0} And {1} = {2}", byteValue, mask, + byteValue And mask) + Next + End Sub +End Module +' The example displays the following output: +' 12 And 254 = 12 +' 123 And 254 = 122 +' 245 And 254 = 244 +' diff --git a/snippets/visualbasic/System/Byte/Overview/bitwise2.vb b/snippets/visualbasic/System/Byte/Overview/bitwise2.vb new file mode 100644 index 00000000000..9525117f6ec --- /dev/null +++ b/snippets/visualbasic/System/Byte/Overview/bitwise2.vb @@ -0,0 +1,48 @@ +' Visual Basic .NET Document + +' +Imports System.Collections.Generic +Imports System.Globalization + +Public Structure ByteString + Public Value As String + Public Sign As Integer +End Structure + +Module Example2 + Public Sub Main() + Dim values() As ByteString = CreateArray(-15, 123, 245) + + Dim mask As Byte = &H14 ' Mask all bits but 2 and 4. + + For Each strValue As ByteString In values + Dim byteValue As Byte = Byte.Parse(strValue.Value, NumberStyles.AllowHexSpecifier) + Console.WriteLine("{0} ({1}) And {2} ({3}) = {4} ({5})", + strValue.Sign * byteValue, + Convert.ToString(byteValue, 2), + mask, Convert.ToString(mask, 2), + (strValue.Sign And Math.Sign(mask)) * (byteValue And mask), + Convert.ToString(byteValue And mask, 2)) + Next + End Sub + + Private Function CreateArray(ParamArray values() As Object) As ByteString() + Dim byteStrings As New List(Of ByteString) + For Each value As Object In values + Dim temp As New ByteString() + Dim sign As Integer = Math.Sign(value) + temp.Sign = sign + ' Change two's complement to magnitude-only representation. + value = value * sign + + temp.Value = Convert.ToString(value, 16) + byteStrings.Add(temp) + Next + Return byteStrings.ToArray() + End Function +End Module +' The example displays the following output: +' -15 (1111) And 20 (10100) = 4 (100) +' 123 (1111011) And 20 (10100) = 16 (10000) +' 245 (11110101) And 20 (10100) = 20 (10100) +' diff --git a/snippets/visualbasic/System/Byte/Overview/byteinstantiate1.vb b/snippets/visualbasic/System/Byte/Overview/byteinstantiate1.vb new file mode 100644 index 00000000000..07d6b831968 --- /dev/null +++ b/snippets/visualbasic/System/Byte/Overview/byteinstantiate1.vb @@ -0,0 +1,69 @@ +' Visual Basic .NET Document +Option Strict On + +Module Example3 + Public Sub Main() + InstantiateByAssignment() + InstantiateByNarrowingConversion() + Parse() + End Sub + + Private Sub InstantiateByAssignment() + ' + Dim value1 As Byte = 64 + Dim value2 As Byte = 255 + ' + End Sub + + Private Sub InstantiateByNarrowingConversion() + ' + Dim int1 As Integer = 128 + Try + Dim value1 As Byte = CByte(int1) + Console.WriteLine(value1) + Catch e As OverflowException + Console.WriteLine("{0} is out of range of a byte.", int1) + End Try + + Dim dbl2 As Double = 3.997 + Try + Dim value2 As Byte = CByte(dbl2) + Console.WriteLine(value2) + Catch e As OverflowException + Console.WriteLine("{0} is out of range of a byte.", dbl2) + End Try + ' The example displays the following output: + ' 128 + ' 4 + ' + End Sub + + Private Sub Parse() + ' + Dim string1 As String = "244" + Try + Dim byte1 As Byte = Byte.Parse(string1) + Console.WriteLine(byte1) + Catch e As OverflowException + Console.WriteLine("'{0}' is out of range of a byte.", string1) + Catch e As FormatException + Console.WriteLine("'{0}' is out of range of a byte.", string1) + End Try + + Dim string2 As String = "F9" + Try + Dim byte2 As Byte = Byte.Parse(string2, + System.Globalization.NumberStyles.HexNumber) + Console.WriteLine(byte2) + Catch e As OverflowException + Console.WriteLine("'{0}' is out of range of a byte.", string2) + Catch e As FormatException + Console.WriteLine("'{0}' is out of range of a byte.", string2) + End Try + ' The example displays the following output: + ' 244 + ' 249 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Byte/Overview/formatting1.vb b/snippets/visualbasic/System/Byte/Overview/formatting1.vb new file mode 100644 index 00000000000..06ccb5a74c4 --- /dev/null +++ b/snippets/visualbasic/System/Byte/Overview/formatting1.vb @@ -0,0 +1,52 @@ +' Visual Basic .NET Document +Option Strict On + +Module Example4 + Public Sub Main() + CallToString() + Console.WriteLine("-----") + CallConvert() + End Sub + + Private Sub CallToString() + ' + Dim numbers() As Byte = {0, 16, 104, 213} + For Each number As Byte In numbers + ' Display value using default formatting. + Console.Write("{0,-3} --> ", number.ToString()) + ' Display value with 3 digits and leading zeros. + Console.Write(number.ToString("D3") + " ") + ' Display value with hexadecimal. + Console.Write(number.ToString("X2") + " ") + ' Display value with four hexadecimal digits. + Console.WriteLine(number.ToString("X4")) + Next + ' The example displays the following output: + ' 0 --> 000 00 0000 + ' 16 --> 016 10 0010 + ' 104 --> 104 68 0068 + ' 213 --> 213 D5 00D5 + ' + End Sub + + Private Sub CallConvert() + ' + Dim numbers() As Byte = {0, 16, 104, 213} + Console.WriteLine("{0} {1,8} {2,5} {3,5}", + "Value", "Binary", "Octal", "Hex") + For Each number As Byte In numbers + Console.WriteLine("{0,5} {1,8} {2,5} {3,5}", + number, Convert.ToString(number, 2), + Convert.ToString(number, 8), + Convert.ToString(number, 16)) + Next + ' The example displays the following output: + ' Value Binary Octal Hex + ' 0 0 0 0 + ' 16 10000 20 10 + ' 104 1101000 150 68 + ' 213 11010101 325 d5 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Char/Overview/GetUnicodeCategory3.vb b/snippets/visualbasic/System/Char/Overview/GetUnicodeCategory3.vb new file mode 100644 index 00000000000..8a87bb1d6c2 --- /dev/null +++ b/snippets/visualbasic/System/Char/Overview/GetUnicodeCategory3.vb @@ -0,0 +1,74 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Globalization + +Module Example1 + Public Sub Main() + ' Define a string with a variety of character categories. + Dim s As String = "The car drove down the narrow, secluded road." + ' Determine the category of each character. + For Each ch In s + Console.WriteLine("'{0}': {1}", ch, Char.GetUnicodeCategory(ch)) + Next + End Sub +End Module +' The example displays the following output: +' 'T': UppercaseLetter +' 'h': LowercaseLetter +' 'e': LowercaseLetter +' ' ': SpaceSeparator +' 'r': LowercaseLetter +' 'e': LowercaseLetter +' 'd': LowercaseLetter +' ' ': SpaceSeparator +' 'c': LowercaseLetter +' 'a': LowercaseLetter +' 'r': LowercaseLetter +' ' ': SpaceSeparator +' 'd': LowercaseLetter +' 'r': LowercaseLetter +' 'o': LowercaseLetter +' 'v': LowercaseLetter +' 'e': LowercaseLetter +' ' ': SpaceSeparator +' 'd': LowercaseLetter +' 'o': LowercaseLetter +' 'w': LowercaseLetter +' 'n': LowercaseLetter +' ' ': SpaceSeparator +' 't': LowercaseLetter +' 'h': LowercaseLetter +' 'e': LowercaseLetter +' ' ': SpaceSeparator +' 'l': LowercaseLetter +' 'o': LowercaseLetter +' 'n': LowercaseLetter +' 'g': LowercaseLetter +' ',': OtherPunctuation +' ' ': SpaceSeparator +' 'n': LowercaseLetter +' 'a': LowercaseLetter +' 'r': LowercaseLetter +' 'r': LowercaseLetter +' 'o': LowercaseLetter +' 'w': LowercaseLetter +' ',': OtherPunctuation +' ' ': SpaceSeparator +' 's': LowercaseLetter +' 'e': LowercaseLetter +' 'c': LowercaseLetter +' 'l': LowercaseLetter +' 'u': LowercaseLetter +' 'd': LowercaseLetter +' 'e': LowercaseLetter +' 'd': LowercaseLetter +' ' ': SpaceSeparator +' 'r': LowercaseLetter +' 'o': LowercaseLetter +' 'a': LowercaseLetter +' 'd': LowercaseLetter +' '.': OtherPunctuation +' + diff --git a/snippets/visualbasic/System/Char/Overview/Project.vbproj b/snippets/visualbasic/System/Char/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Char/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Char/Overview/grapheme1.vb b/snippets/visualbasic/System/Char/Overview/grapheme1.vb new file mode 100644 index 00000000000..ad93be4dbe3 --- /dev/null +++ b/snippets/visualbasic/System/Char/Overview/grapheme1.vb @@ -0,0 +1,18 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO + +Module Example2 + Public Sub Main() + Dim sw As New StreamWriter("chars1.txt") + Dim chars() As Char = {ChrW(&H61), ChrW(&H308)} + Dim strng As New String(chars) + sw.WriteLine(strng) + sw.Close() + End Sub +End Module +' The example produces the following output: +' ä +' diff --git a/snippets/visualbasic/System/Char/Overview/normalized.vb b/snippets/visualbasic/System/Char/Overview/normalized.vb new file mode 100644 index 00000000000..9aeffac27ef --- /dev/null +++ b/snippets/visualbasic/System/Char/Overview/normalized.vb @@ -0,0 +1,28 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example3 + Public Sub Main() + Dim combining As String = ChrW(&H61) + ChrW(&H308) + ShowString(combining) + + Dim normalized As String = combining.Normalize() + ShowString(normalized) + End Sub + + Private Sub ShowString(s As String) + Console.Write("Length of string: {0} (", s.Length) + For ctr As Integer = 0 To s.Length - 1 + Console.Write("U+{0:X4}", Convert.ToUInt16(s(ctr))) + If ctr <> s.Length - 1 Then Console.Write(" ") + Next + Console.WriteLine(")") + Console.WriteLine() + End Sub +End Module +' The example displays the following output: +' Length of string: 2 (U+0061 U+0308) +' +' Length of string: 1 (U+00E4) +' diff --git a/snippets/visualbasic/System/Char/Overview/surrogate1.vb b/snippets/visualbasic/System/Char/Overview/surrogate1.vb new file mode 100644 index 00000000000..59d27a79c68 --- /dev/null +++ b/snippets/visualbasic/System/Char/Overview/surrogate1.vb @@ -0,0 +1,27 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO + +Module Example4 + Public Sub Main() + Dim sw As New StreamWriter(".\chars2.txt") + Dim utf32 As Integer = &H1D160 + Dim surrogate As String = Char.ConvertFromUtf32(utf32) + sw.WriteLine("U+{0:X6} UTF-32 = {1} ({2}) UTF-16", + utf32, surrogate, ShowCodePoints(surrogate)) + sw.Close() + End Sub + + Private Function ShowCodePoints(value As String) As String + Dim retval As String = Nothing + For Each ch In value + retval += String.Format("U+{0:X4} ", Convert.ToUInt16(ch)) + Next + Return retval.Trim() + End Function +End Module +' The example produces the following output: +' U+01D160 UTF-32 = ð (U+D834 U+DD60) UTF-16 +' diff --git a/snippets/visualbasic/System/Char/Overview/textelements2.vb b/snippets/visualbasic/System/Char/Overview/textelements2.vb new file mode 100644 index 00000000000..c71e91c70ca --- /dev/null +++ b/snippets/visualbasic/System/Char/Overview/textelements2.vb @@ -0,0 +1,16 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example5 + Public Sub Main() + Dim result As String = String.Empty + For ctr As Integer = &H10107 To &H10110 ' Range of Aegean numbers. + result += Char.ConvertFromUtf32(ctr) + Next + Console.WriteLine("The string contains {0} characters.", result.Length) + End Sub +End Module +' The example displays the following output: +' The string contains 20 characters. +' diff --git a/snippets/visualbasic/System/Char/Overview/textelements2a.vb b/snippets/visualbasic/System/Char/Overview/textelements2a.vb new file mode 100644 index 00000000000..f6c71a0d154 --- /dev/null +++ b/snippets/visualbasic/System/Char/Overview/textelements2a.vb @@ -0,0 +1,19 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Globalization + +Module Example6 + Public Sub Main() + Dim result As String = String.Empty + For ctr As Integer = &H10107 To &H10110 ' Range of Aegean numbers. + result += Char.ConvertFromUtf32(ctr) + Next + Dim si As New StringInfo(result) + Console.WriteLine("The string contains {0} characters.", si.LengthInTextElements) + End Sub +End Module +' The example displays the following output: +' The string contains 10 characters. +' diff --git a/snippets/visualbasic/System/Console/Overview/Project.vbproj b/snippets/visualbasic/System/Console/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Console/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Console/Overview/example3.vb b/snippets/visualbasic/System/Console/Overview/example3.vb new file mode 100644 index 00000000000..d18c90ab074 --- /dev/null +++ b/snippets/visualbasic/System/Console/Overview/example3.vb @@ -0,0 +1,174 @@ + +' dump a range of Unicode characters as a 16x16 array +' +Imports System.IO +Imports System.Globalization +Imports System.Text + +Public Module DisplayChars + Public Sub Main(args() As String) + Dim rangeStart As UInteger = 0 + Dim rangeEnd As UInteger = 0 + Dim setOutputEncodingToUnicode As Boolean = True + ' Get the current encoding so we can restore it. + Dim originalOutputEncoding As Encoding = Console.OutputEncoding + + Try + Select Case args.Length + Case 2 + rangeStart = UInt32.Parse(args(0), NumberStyles.HexNumber) + rangeEnd = UInt32.Parse(args(1), NumberStyles.HexNumber) + setOutputEncodingToUnicode = True + Case 3 + If Not UInt32.TryParse(args(0), NumberStyles.HexNumber, Nothing, rangeStart) Then + Throw New ArgumentException(String.Format("{0} is not a valid hexadecimal number.", args(0))) + End If + + If Not UInt32.TryParse(args(1), NumberStyles.HexNumber, Nothing, rangeEnd) Then + Throw New ArgumentException(String.Format("{0} is not a valid hexadecimal number.", args(1))) + End If + + Boolean.TryParse(args(2), setOutputEncodingToUnicode) + Case Else + Console.WriteLine("Usage: {0} <{1}> <{2}> [{3}]", + Environment.GetCommandLineArgs()(0), + "startingCodePointInHex", + "endingCodePointInHex", + "") + Exit Sub + End Select + + If setOutputEncodingToUnicode Then + ' This won't work before .NET Framework 4.5. + Try + ' Set encoding Imports endianness of this system. + ' We're interested in displaying individual Char objects, so + ' we don't want a Unicode BOM or exceptions to be thrown on + ' invalid Char values. + Console.OutputEncoding = New UnicodeEncoding(Not BitConverter.IsLittleEndian, False) + Console.WriteLine("{0}Output encoding set to UTF-16", vbCrLf) + Catch e As IOException + Console.OutputEncoding = New UTF8Encoding() + Console.WriteLine("Output encoding set to UTF-8") + End Try + Else + Console.WriteLine("The console encoding is {0} (code page {1})", + Console.OutputEncoding.EncodingName, + Console.OutputEncoding.CodePage) + End If + DisplayRange(rangeStart, rangeEnd) + Catch ex As ArgumentException + Console.WriteLine(ex.Message) + Finally + ' Restore console environment. + Console.OutputEncoding = originalOutputEncoding + End Try + End Sub + + Public Sub DisplayRange(rangeStart As UInteger, rangeEnd As UInteger) + Const upperRange As UInteger = &h10FFFF + Const surrogateStart As UInteger = &hD800 + Const surrogateEnd As UInteger = &hDFFF + + If rangeEnd <= rangeStart Then + Dim t As UInteger = rangeStart + rangeStart = rangeEnd + rangeEnd = t + End If + + ' Check whether the start or end range is outside of last plane. + If rangeStart > upperRange Then + Throw New ArgumentException(String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{1:X5})", + rangeStart, upperRange)) + End If + If rangeEnd > upperRange Then + Throw New ArgumentException(String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{0:X5})", + rangeEnd, upperRange)) + End If + ' Since we're using 21-bit code points, we can't use U+D800 to U+DFFF. + If (rangeStart < surrogateStart And rangeEnd > surrogateStart) OrElse (rangeStart >= surrogateStart And rangeStart <= surrogateEnd ) + Throw New ArgumentException(String.Format("0x{0:X5}-0x{1:X5} includes the surrogate pair range 0x{2:X5}-0x{3:X5}", + rangeStart, rangeEnd, surrogateStart, surrogateEnd)) + End If + + Dim last As UInteger = RoundUpToMultipleOf(&h10, rangeEnd) + Dim first As UInteger = RoundDownToMultipleOf(&h10, rangeStart) + + Dim rows As UInteger = (last - first) \ &h10 + + For r As UInteger = 0 To rows - 1 + ' Display the row header. + Console.Write("{0:x5} ", first + &h10 * r) + + For c As UInteger = 1 To &h10 + Dim cur As UInteger = first + &h10 * r + c + If cur < rangeStart Then + Console.Write(" {0} ", Convert.ToChar(&h20)) + Else If rangeEnd < cur Then + Console.Write(" {0} ", Convert.ToChar(&h20)) + Else + ' the cast to int is safe, since we know that val <= upperRange. + Dim chars As String = Char.ConvertFromUtf32(CInt(cur)) + ' Display a space for code points that are not valid characters. + If CharUnicodeInfo.GetUnicodeCategory(chars(0)) = + UnicodeCategory.OtherNotAssigned Then + Console.Write(" {0} ", Convert.ToChar(&h20)) + ' Display a space for code points in the private use area. + Else If CharUnicodeInfo.GetUnicodeCategory(chars(0)) = + UnicodeCategory.PrivateUse Then + Console.Write(" {0} ", Convert.ToChar(&h20)) + ' Is surrogate pair a valid character? + ' Note that the console will interpret the high and low surrogate + ' as separate (and unrecognizable) characters. + Else If chars.Length > 1 AndAlso CharUnicodeInfo.GetUnicodeCategory(chars, 0) = + UnicodeCategory.OtherNotAssigned Then + Console.Write(" {0} ", Convert.ToChar(&h20)) + Else + Console.Write(" {0} ", chars) + End If + End If + + Select Case c + Case 3, 11 + Console.Write("-") + Case 7 + Console.Write("--") + End Select + Next + + Console.WriteLine() + If 0 < r AndAlso r Mod &h10 = 0 + Console.WriteLine() + End If + Next + End Sub + + Private Function RoundUpToMultipleOf(b As UInteger, u As UInteger) As UInteger + Return RoundDownToMultipleOf(b, u) + b + End Function + + Private Function RoundDownToMultipleOf(b As UInteger, u As UInteger) As UInteger + Return u - (u Mod b) + End Function +End Module +' If the example is run with the command line +' DisplayChars 0400 04FF true +' the example displays the Cyrillic character set as follows: +' Output encoding set to UTF-16 +' 00400 Ѐ Ё Ђ Ѓ - Є Ѕ І Ї -- Ј Љ Њ Ћ - Ќ Ѝ Ў Џ +' 00410 А Б В Г - Д Е Ж З -- И Й К Л - М Н О П +' 00420 Р С Т У - Ф Х Ц Ч -- Ш Щ Ъ Ы - Ь Э Ю Я +' 00430 а б в г - д е ж з -- и й к л - м н о п +' 00440 р с т у - ф х ц ч -- ш щ ъ ы - ь э ю я +' 00450 ѐ ё ђ ѓ - є ѕ і ї -- ј љ њ ћ - ќ ѝ ў џ +' 00460 Ѡ ѡ Ѣ ѣ - Ѥ ѥ Ѧ ѧ -- Ѩ ѩ Ѫ ѫ - Ѭ ѭ Ѯ ѯ +' 00470 Ѱ ѱ Ѳ ѳ - Ѵ ѵ Ѷ ѷ -- Ѹ ѹ Ѻ ѻ - Ѽ ѽ Ѿ ѿ +' 00480 Ҁ ҁ ҂ ҃ - ҄ ҅ ҆ ҇ -- ҈ ҉ Ҋ ҋ - Ҍ ҍ Ҏ ҏ +' 00490 Ґ ґ Ғ ғ - Ҕ ҕ Җ җ -- Ҙ ҙ Қ қ - Ҝ ҝ Ҟ ҟ +' 004a0 Ҡ ҡ Ң ң - Ҥ ҥ Ҧ ҧ -- Ҩ ҩ Ҫ ҫ - Ҭ ҭ Ү ү +' 004b0 Ұ ұ Ҳ ҳ - Ҵ ҵ Ҷ ҷ -- Ҹ ҹ Һ һ - Ҽ ҽ Ҿ ҿ +' 004c0 Ӏ Ӂ ӂ Ӄ - ӄ Ӆ ӆ Ӈ -- ӈ Ӊ ӊ Ӌ - ӌ Ӎ ӎ ӏ +' 004d0 Ӑ ӑ Ӓ ӓ - Ӕ ӕ Ӗ ӗ -- Ә ә Ӛ ӛ - Ӝ ӝ Ӟ ӟ +' 004e0 Ӡ ӡ Ӣ ӣ - Ӥ ӥ Ӧ ӧ -- Ө ө Ӫ ӫ - Ӭ ӭ Ӯ ӯ +' 004f0 Ӱ ӱ Ӳ ӳ - Ӵ ӵ Ӷ ӷ -- Ӹ ӹ Ӻ ӻ - Ӽ ӽ Ӿ ӿ +' diff --git a/snippets/visualbasic/System/Console/Overview/fontlink1.vb b/snippets/visualbasic/System/Console/Overview/fontlink1.vb new file mode 100644 index 00000000000..6e3624de869 --- /dev/null +++ b/snippets/visualbasic/System/Console/Overview/fontlink1.vb @@ -0,0 +1,68 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports Microsoft.Win32 + +Module Example2 + Public Sub Main() + Dim valueName As String = "Lucida Console" + Dim newFont As String = "simsun.ttc,SimSun" + Dim fonts() As String = Nothing + Dim kind As RegistryValueKind + Dim toAdd As Boolean + + Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey( + "Software\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink", + True) + If key Is Nothing Then + Console.WriteLine("Font linking is not enabled.") + Else + ' Determine if the font is a base font. + Dim names() As String = key.GetValueNames() + If Array.Exists(names, Function(s) s.Equals(valueName, + StringComparison.OrdinalIgnoreCase)) Then + ' Get the value's type. + kind = key.GetValueKind(valueName) + + ' Type should be RegistryValueKind.MultiString, but we can't be sure. + Select Case kind + Case RegistryValueKind.String + fonts = {CStr(key.GetValue(valueName))} + Case RegistryValueKind.MultiString + fonts = CType(key.GetValue(valueName), String()) + Case RegistryValueKind.None + ' Do nothing. + fonts = {} + End Select + ' Determine whether SimSun is a linked font. + If Array.FindIndex(fonts, Function(s) s.IndexOf("SimSun", + StringComparison.OrdinalIgnoreCase) >= 0) >= 0 Then + Console.WriteLine("Font is already linked.") + toAdd = False + Else + ' Font is not a linked font. + toAdd = True + End If + Else + ' Font is not a base font. + toAdd = True + fonts = {} + End If + + If toAdd Then + Array.Resize(fonts, fonts.Length + 1) + fonts(fonts.GetUpperBound(0)) = newFont + ' Change REG_SZ to REG_MULTI_SZ. + If kind = RegistryValueKind.String Then + key.DeleteValue(valueName, False) + End If + key.SetValue(valueName, fonts, RegistryValueKind.MultiString) + Console.WriteLine("SimSun added to the list of linked fonts.") + End If + End If + + If key IsNot Nothing Then key.Close() + End Sub +End Module +' diff --git a/snippets/visualbasic/System/Console/Overview/normalize1.vb b/snippets/visualbasic/System/Console/Overview/normalize1.vb new file mode 100644 index 00000000000..7f2e39ad66d --- /dev/null +++ b/snippets/visualbasic/System/Console/Overview/normalize1.vb @@ -0,0 +1,19 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example3 + Public Sub Main() + Dim chars() As Char = {ChrW(&H61), ChrW(&H308)} + + Dim combining As String = New String(chars) + Console.WriteLine(combining) + + combining = combining.Normalize() + Console.WriteLine(combining) + End Sub +End Module +' The example displays the following output: +' a" +' ä +' diff --git a/snippets/visualbasic/System/Console/Overview/setfont1.vb b/snippets/visualbasic/System/Console/Overview/setfont1.vb new file mode 100644 index 00000000000..f633effed0b --- /dev/null +++ b/snippets/visualbasic/System/Console/Overview/setfont1.vb @@ -0,0 +1,75 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Runtime.InteropServices + +Public Module Example5 + ' + Private Declare Function GetStdHandle Lib "Kernel32" ( + nStdHandle As Integer) As IntPtr + + ' [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + Private Declare Function GetCurrentConsoleFontEx Lib "Kernel32" ( + consoleOutput As IntPtr, + maximumWindow As Boolean, + ByRef lpConsoleCurrentFontEx As CONSOLE_FONT_INFO_EX) As Boolean + + ' [DllImport("kernel32.dll", SetLastError = true)] + Private Declare Function SetCurrentConsoleFontEx Lib "Kernel32" ( + consoleOutput As IntPtr, + maximumWindow As Boolean, + consoleCurrentFontEx As CONSOLE_FONT_INFO_EX) As Boolean + + Private Const STD_OUTPUT_HANDLE As Integer = -11 + Private Const TMPF_TRUETYPE As Integer = 4 + Private Const LF_FACESIZE As Integer = 32 + Private INVALID_HANDLE_VALUE As IntPtr = New IntPtr(-1) + + Public Sub Main() + Dim fontName As String = "Lucida Console" + Dim hnd As IntPtr = GetStdHandle(STD_OUTPUT_HANDLE) + If hnd <> INVALID_HANDLE_VALUE Then + Dim info As CONSOLE_FONT_INFO_EX = New CONSOLE_FONT_INFO_EX() + info.cbSize = CUInt(Marshal.SizeOf(info)) + Dim tt As Boolean = False + ' First determine whether there's already a TrueType font. + If GetCurrentConsoleFontEx(hnd, False, info) Then + tt = (info.FontFamily And TMPF_TRUETYPE) = TMPF_TRUETYPE + If tt Then + Console.WriteLine("The console already is using a TrueType font.") + Return + End If + ' Set console font to Lucida Console. + Dim newInfo As CONSOLE_FONT_INFO_EX = New CONSOLE_FONT_INFO_EX() + newInfo.cbSize = CUInt(Marshal.SizeOf(newInfo)) + newInfo.FontFamily = TMPF_TRUETYPE + newInfo.FaceName = fontName + ' Get some settings from current font. + newInfo.dwFontSize = New COORD(info.dwFontSize.X, info.dwFontSize.Y) + newInfo.FontWeight = info.FontWeight + SetCurrentConsoleFontEx(hnd, False, newInfo) + End If + End If + End Sub + + Friend Structure COORD + Friend X As Short + Friend Y As Short + + Friend Sub New(x As Short, y As Short) + Me.X = x + Me.Y = y + End Sub + End Structure + + Friend Structure CONSOLE_FONT_INFO_EX + Friend cbSize As UInteger + Friend nFont As UInteger + Friend dwFontSize As COORD + Friend FontFamily As Integer + Friend FontWeight As Integer + Friend FaceName As String + End Structure +End Module +' diff --git a/snippets/visualbasic/System/Console/Overview/source.vb b/snippets/visualbasic/System/Console/Overview/source.vb new file mode 100644 index 00000000000..5b489ba0ae9 --- /dev/null +++ b/snippets/visualbasic/System/Console/Overview/source.vb @@ -0,0 +1,17 @@ +' +Public Class Example4 + Public Shared Sub Main() + Console.Write("Hello ") + Console.WriteLine("World!") + Console.Write("Enter your name: ") + Dim name As String = Console.ReadLine() + Console.Write("Good day, ") + Console.Write(name) + Console.WriteLine("!") + End Sub +End Class +' The example displays output similar to the following: +' Hello World! +' Enter your name: James +' Good day, James! +' diff --git a/snippets/visualbasic/System/Console/Overview/unicode1.vb b/snippets/visualbasic/System/Console/Overview/unicode1.vb new file mode 100644 index 00000000000..7ef4bfcf698 --- /dev/null +++ b/snippets/visualbasic/System/Console/Overview/unicode1.vb @@ -0,0 +1,33 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example + Public Sub Main() + ' Create a Char array for the modern Cyrillic alphabet, + ' from U+0410 to U+044F. + Dim nChars As Integer = &h44F - &h0410 + Dim chars(nChars) As Char + Dim codePoint As UInt16 = &h0410 + For ctr As Integer = 0 To chars.Length - 1 + chars(ctr) = ChrW(codePoint) + codePoint += CType(1, UShort) + Next + + Console.WriteLine("Current code page: {0}", + Console.OutputEncoding.CodePage) + Console.WriteLine() + ' Display the characters. + For Each ch In chars + Console.Write("{0} ", ch) + If Console.CursorLeft >= 70 Then Console.WriteLine() + Next + End Sub +End Module +' The example displays the following output: +' Current code page: 437 +' +' ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? +' ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? +' ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? +' diff --git a/snippets/visualbasic/System/Convert/Overview/NonDecimal1.vb b/snippets/visualbasic/System/Convert/Overview/NonDecimal1.vb new file mode 100644 index 00000000000..9495423ab5b --- /dev/null +++ b/snippets/visualbasic/System/Convert/Overview/NonDecimal1.vb @@ -0,0 +1,23 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example2 + Public Sub Main() + Dim baseValues() As Integer = {2, 8, 10, 16} + Dim value As Short = Int16.MaxValue + For Each baseValue In baseValues + Dim s As String = Convert.ToString(value, baseValue) + Dim value2 As Short = Convert.ToInt16(s, baseValue) + + Console.WriteLine("{0} --> {1} (base {2}) --> {3}", + value, s, baseValue, value2) + Next + End Sub +End Module +' The example displays the following output: +' 32767 --> 111111111111111 (base 2) --> 32767 +' 32767 --> 77777 (base 8) --> 32767 +' 32767 --> 32767 (base 10) --> 32767 +' 32767 --> 7fff (base 16) --> 32767 +' diff --git a/snippets/visualbasic/System/Convert/Overview/Project.vbproj b/snippets/visualbasic/System/Convert/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Convert/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Convert/Overview/converter.vb b/snippets/visualbasic/System/Convert/Overview/converter.vb new file mode 100644 index 00000000000..10ae06b1b1a --- /dev/null +++ b/snippets/visualbasic/System/Convert/Overview/converter.vb @@ -0,0 +1,59 @@ +Option Strict On + +Namespace ConvertSnippet + 'This class is the snippet for the class System.Convert + Class Converter + + Public Shared Sub Main() + ' + Dim dNumber As Double + dNumber = 23.15 + + Try + ' Returns 23 + Dim iNumber As Integer + iNumber = System.Convert.ToInt32(dNumber) + Catch exp As System.OverflowException + System.Console.WriteLine("Overflow in double to int conversion.") + End Try + + ' Returns True + Dim bNumber As Boolean + bNumber = System.Convert.ToBoolean(dNumber) + + ' Returns "23.15" + Dim strNumber As String + strNumber = System.Convert.ToString(dNumber) + + Try + ' Returns '2' + Dim chrNumber As Char + chrNumber = System.Convert.ToChar(strNumber.Chars(1)) + Catch exp As System.ArgumentNullException + System.Console.WriteLine("String is null.") + Catch exp As System.FormatException + System.Console.WriteLine("String length is greater than 1.") + End Try + + ' System.Console.ReadLine() returns a string and it + ' must be converted. + Dim newInteger As Integer + newInteger = 0 + Try + System.Console.WriteLine("Enter an integer:") + newInteger = System.Convert.ToInt32(System.Console.ReadLine()) + Catch exp As System.ArgumentNullException + System.Console.WriteLine("String is null.") + Catch exp As System.FormatException + System.Console.WriteLine("String does not consist of an " + _ + "optional sign followed by a series of digits.") + Catch exp As System.OverflowException + System.Console.WriteLine("Overflow in string to int conversion.") + End Try + + System.Console.WriteLine("Your integer as a double is {0}", _ + System.Convert.ToDouble(newInteger)) + ' + End Sub + End Class +End Namespace diff --git a/snippets/visualbasic/System/Convert/Overview/tobyte1.vb b/snippets/visualbasic/System/Convert/Overview/tobyte1.vb new file mode 100644 index 00000000000..e4d4a1f6abc --- /dev/null +++ b/snippets/visualbasic/System/Convert/Overview/tobyte1.vb @@ -0,0 +1,267 @@ +' Visual Basic .NET Document +Option Strict On + +Module Example3 + Public Sub Main() + ConvertBoolean() + Console.WriteLine("-----") + ConvertChar() + Console.WriteLine("-----") + ConvertInt16() + Console.WriteLine("-----") + ConvertInt32() + Console.WriteLine("-----") + ConvertInt64() + Console.WriteLine("-----") + ConvertObject() + Console.WriteLine("-----") + ConvertSByte() + Console.WriteLine("-----") + ConvertUInt16() + Console.WriteLine("-----") + ConvertUInt32() + Console.WriteLine("-----") + ConvertUInt64() + End Sub + + Private Sub ConvertBoolean() + ' + Dim falseFlag As Boolean = False + Dim trueFlag As Boolean = True + + Console.WriteLine("{0} converts to {1}.", falseFlag, + Convert.ToByte(falseFlag)) + Console.WriteLine("{0} converts to {1}.", trueFlag, + Convert.ToByte(trueFlag)) + ' The example displays the following output: + ' False converts to 0. + ' True converts to 1. + ' + End Sub + + Private Sub ConvertChar() + ' + Dim chars() As Char = {"a"c, "z"c, ChrW(7), ChrW(1023)} + For Each ch As Char In chars + Try + Dim result As Byte = Convert.ToByte(ch) + Console.WriteLine("{0} is converted to {1}.", ch, result) + Catch e As OverflowException + Console.WriteLine("Unable to convert u+{0} to a byte.", + AscW(ch).ToString("X4")) + End Try + Next + ' The example displays the following output: + ' a is converted to 97. + ' z is converted to 122. + ' is converted to 7. + ' Unable to convert u+03FF to a byte. + ' + End Sub + + Private Sub ConvertInt16() + ' + Dim numbers() As Short = {Int16.MinValue, -1, 0, 121, 340, Int16.MaxValue} + Dim result As Byte + For Each number As Short In numbers + Try + result = Convert.ToByte(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Byte type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' The Int16 value -32768 is outside the range of the Byte type. + ' The Int16 value -1 is outside the range of the Byte type. + ' Converted the Int16 value 0 to the Byte value 0. + ' Converted the Int16 value 121 to the Byte value 121. + ' The Int16 value 340 is outside the range of the Byte type. + ' The Int16 value 32767 is outside the range of the Byte type. + ' + End Sub + + Private Sub ConvertInt32() + ' + Dim numbers() As Integer = {Int32.MinValue, -1, 0, 121, 340, Int32.MaxValue} + Dim result As Byte + For Each number As Integer In numbers + Try + result = Convert.ToByte(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Byte type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' The Int32 value -2147483648 is outside the range of the Byte type. + ' The Int32 value -1 is outside the range of the Byte type. + ' Converted the Int32 value 0 to the Byte value 0. + ' Converted the Int32 value 121 to the Byte value 121. + ' The Int32 value 340 is outside the range of the Byte type. + ' The Int32 value 2147483647 is outside the range of the Byte type. + ' + End Sub + + Private Sub ConvertInt64() + ' + Dim numbers() As Long = {Int64.MinValue, -1, 0, 121, 340, Int64.MaxValue} + Dim result As Byte + For Each number As Long In numbers + Try + result = Convert.ToByte(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Byte type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' The Int64 value -9223372036854775808 is outside the range of the Byte type. + ' The Int64 value -1 is outside the range of the Byte type. + ' Converted the Int64 value 0 to the Byte value 0. + ' Converted the Int64 value 121 to the Byte value 121. + ' The Int64 value 340 is outside the range of the Byte type. + ' The Int64 value 9223372036854775807 is outside the range of the Byte type. + ' + End Sub + + Private Sub ConvertObject() + ' + Dim values() As Object = {True, -12, 163, 935, "x"c, "104", "103.0", "-1", + "1.00e2", "One", 100.0} + Dim result As Byte + For Each value As Object In values + Try + result = Convert.ToByte(value) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + value.GetType().Name, value, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Byte type.", + value.GetType().Name, value) + Catch e As FormatException + Console.WriteLine("The {0} value {1} is not in a recognizable format.", + value.GetType().Name, value) + Catch e As InvalidCastException + Console.WriteLine("No conversion to a Byte exists for the {0} value {1}.", + value.GetType().Name, value) + + End Try + Next + ' The example displays the following output: + ' Converted the Boolean value True to the Byte value 1. + ' The Int32 value -12 is outside the range of the Byte type. + ' Converted the Int32 value 163 to the Byte value 163. + ' The Int32 value 935 is outside the range of the Byte type. + ' Converted the Char value x to the Byte value 120. + ' Converted the String value 104 to the Byte value 104. + ' The String value 103.0 is not in a recognizable format. + ' The String value -1 is outside the range of the Byte type. + ' The String value 1.00e2 is not in a recognizable format. + ' The String value One is not in a recognizable format. + ' Converted the Double value 100 to the Byte value 100. + ' + End Sub + + Private Sub ConvertSByte() + ' + Dim numbers() As SByte = {SByte.MinValue, -1, 0, 10, SByte.MaxValue} + Dim result As Byte + For Each number As SByte In numbers + Try + result = Convert.ToByte(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Byte type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' The SByte value -128 is outside the range of the Byte type. + ' The SByte value -1 is outside the range of the Byte type. + ' Converted the SByte value 0 to the Byte value 0. + ' Converted the SByte value 10 to the Byte value 10. + ' Converted the SByte value 127 to the Byte value 127. + ' + End Sub + + Private Sub ConvertUInt16() + ' + Dim numbers() As UShort = {UInt16.MinValue, 121, 340, UInt16.MaxValue} + Dim result As Byte + For Each number As UShort In numbers + Try + result = Convert.ToByte(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Byte type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' Converted the UInt16 value 0 to the Byte value 0. + ' Converted the UInt16 value 121 to the Byte value 121. + ' The UInt16 value 340 is outside the range of the Byte type. + ' The UInt16 value 65535 is outside the range of the Byte type. + ' + End Sub + + Private Sub ConvertUInt32() + ' + Dim numbers() As UInteger = {UInt32.MinValue, 121, 340, UInt32.MaxValue} + Dim result As Byte + For Each number As UInteger In numbers + Try + result = Convert.ToByte(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Byte type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' Converted the UInt32 value 0 to the Byte value 0. + ' Converted the UInt32 value 121 to the Byte value 121. + ' The UInt32 value 340 is outside the range of the Byte type. + ' The UInt32 value 4294967295 is outside the range of the Byte type. + ' + End Sub + + Private Sub ConvertUInt64() + ' + Dim numbers() As ULong = {UInt64.MinValue, 121, 340, UInt64.MaxValue} + Dim result As Byte + For Each number As ULong In numbers + Try + result = Convert.ToByte(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Byte type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' Converted the UInt64 value 0 to the Byte value 0. + ' Converted the UInt64 value 121 to the Byte value 121. + ' The UInt64 value 340 is outside the range of the Byte type. + ' The UInt64 value 18446744073709551615 is outside the range of the Byte type. + ' + End Sub +End Module diff --git a/snippets/visualbasic/System/Convert/Overview/toint32_1.vb b/snippets/visualbasic/System/Convert/Overview/toint32_1.vb new file mode 100644 index 00000000000..36363c28182 --- /dev/null +++ b/snippets/visualbasic/System/Convert/Overview/toint32_1.vb @@ -0,0 +1,388 @@ +' Visual Basic .NET Document +Option Strict On + +Module modMain + Public Sub Main() + ConvertBoolean() + Console.WriteLine("-----") + ConvertByte() + Console.WriteLine("-----") + ConvertChar() + Console.WriteLine("-----") + ConvertDecimal() + Console.WriteLine("-----") + ConvertDouble() + Console.WriteLine("-----") + ConvertInt16() + Console.WriteLine("-----") + ConvertInt64() + Console.WriteLine("-----") + ConvertObject() + Console.WriteLine("-----") + ConvertSByte() + Console.WriteLine("-----") + ConvertSingle() + Console.WriteLine("----") + ConvertString() ' NEW + Console.WriteLine("-----") + ConvertUInt16() + Console.WriteLine("-----") + ConvertUInt32() + Console.WriteLine("-----") + ConvertUInt64() + End Sub + + Private Sub ConvertBoolean() + ' + Dim falseFlag As Boolean = False + Dim trueFlag As Boolean = True + + Console.WriteLine("{0} converts to {1}.", falseFlag, _ + Convert.ToInt32(falseFlag)) + Console.WriteLine("{0} converts to {1}.", trueFlag, _ + Convert.ToInt32(trueFlag)) + ' The example displays the following output: + ' False converts to 0. + ' True converts to 1. + ' + End Sub + + Private Sub ConvertByte() + ' + Dim bytes() As Byte = { Byte.MinValue, 14, 122, Byte.MaxValue} + Dim result As Integer + + For Each byteValue As Byte In bytes + result = Convert.ToInt32(byteValue) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", _ + byteValue.GetType().Name, byteValue, _ + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the Byte value 0 to the Int32 value 0. + ' Converted the Byte value 14 to the Int32 value 14. + ' Converted the Byte value 122 to the Int32 value 122. + ' Converted the Byte value 255 to the Int32 value 255. + ' + End Sub + + Private Sub ConvertChar() + ' + Dim chars() As Char = { "a"c, "z"c, ChrW(7), ChrW(1023), _ + ChrW(Short.MaxValue), ChrW(&hFFFE) } + Dim result As Integer + + For Each ch As Char in chars + Try + result = Convert.ToInt32(ch) + Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.", _ + ch.GetType().Name, ch, _ + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("Unable to convert u+{0} to an Int32.", _ + AscW(ch).ToString("X4")) + End Try + Next + ' The example displays the following output: + ' Converted the Char value 'a' to the Int32 value 97. + ' Converted the Char value 'z' to the Int32 value 122. + ' Converted the Char value '' to the Int32 value 7. + ' Converted the Char value 'Ͽ' to the Int32 value 1023. + ' Converted the Char value '翿' to the Int32 value 32767. + ' Converted the Char value '￾' to the Int32 value 65534. + ' + End Sub + + Private Sub ConvertDecimal() + ' + Dim values() As Decimal = { Decimal.MinValue, -1034.23d, -12d, 0d, 147d, _ + 199.55d, 9214.16d, Decimal.MaxValue } + Dim result As Integer + + For Each value As Decimal In values + Try + result = Convert.ToInt32(value) + Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.", _ + value.GetType().Name, value, _ + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("{0} is outside the range of the Int32 type.", _ + value) + End Try + Next + ' The example displays the following output: + ' -79228162514264337593543950335 is outside the range of the Int32 type. + ' Converted the Decimal value '-1034.23' to the Int32 value -1034. + ' Converted the Decimal value '-12' to the Int32 value -12. + ' Converted the Decimal value '0' to the Int32 value 0. + ' Converted the Decimal value '147' to the Int32 value 147. + ' Converted the Decimal value '199.55' to the Int32 value 200. + ' Converted the Decimal value '9214.16' to the Int32 value 9214. + ' 79228162514264337593543950335 is outside the range of the Int32 type. + ' + End Sub + + Private Sub ConvertDouble() + ' + Dim values() As Double = { Double.MinValue, -1.38e10, -1023.299, -12.98, _ + 0, 9.113e-16, 103.919, 17834.191, Double.MaxValue } + Dim result As Integer + + For Each value As Double In values + Try + result = Convert.ToInt32(value) + Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.", _ + value.GetType().Name, value, _ + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("{0} is outside the range of the Int32 type.", value) + End Try + Next + ' -1.79769313486232E+308 is outside the range of the Int32 type. + ' -13800000000 is outside the range of the Int32 type. + ' Converted the Double value '-1023.299' to the Int32 value -1023. + ' Converted the Double value '-12.98' to the Int32 value -13. + ' Converted the Double value '0' to the Int32 value 0. + ' Converted the Double value '9.113E-16' to the Int32 value 0. + ' Converted the Double value '103.919' to the Int32 value 104. + ' Converted the Double value '17834.191' to the Int32 value 17834. + ' 1.79769313486232E+308 is outside the range of the Int32 type. + ' + End Sub + + Private Sub ConvertInt16() + ' + Dim numbers() As Short = { Int16.MinValue, -1, 0, 121, 340, Int16.MaxValue } + Dim result As Integer + + For Each number As Short In numbers + result = Convert.ToInt32(number) + Console.WriteLine("Converted the {0} value {1} to a {2} value {3}.", _ + number.GetType().Name, number, _ + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the Int16 value -32768 to a Int32 value -32768. + ' Converted the Int16 value -1 to a Int32 value -1. + ' Converted the Int16 value 0 to a Int32 value 0. + ' Converted the Int16 value 121 to a Int32 value 121. + ' Converted the Int16 value 340 to a Int32 value 340. + ' Converted the Int16 value 32767 to a Int32 value 32767. + ' + End Sub + + Private Sub ConvertInt64 + ' + Dim numbers() As Long = { Int64.MinValue, -1, 0, 121, 340, Int64.MaxValue } + Dim result As Integer + For Each number As Long In numbers + Try + result = Convert.ToInt32(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", _ + number.GetType().Name, number, _ + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.", _ + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' The Int64 value -9223372036854775808 is outside the range of the Int32 type. + ' Converted the Int64 value -1 to the Int32 value -1. + ' Converted the Int64 value 0 to the Int32 value 0. + ' Converted the Int64 value 121 to the Int32 value 121. + ' Converted the Int64 value 340 to the Int32 value 340. + ' The Int64 value 9223372036854775807 is outside the range of the Int32 type. + ' + End Sub + + Private Sub ConvertObject() + ' + Dim values() As Object = { True, -12, 163, 935, "x"c, #5/12/2009#, _ + "104", "103.0", "-1", _ + "1.00e2", "One", 1.00e2, 16.3e42} + Dim result As Integer + + For Each value As Object In values + Try + result = Convert.ToInt32(value) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", _ + value.GetType().Name, value, _ + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.", _ + value.GetType().Name, value) + Catch e As FormatException + Console.WriteLine("The {0} value {1} is not in a recognizable format.", _ + value.GetType().Name, value) + Catch e As InvalidCastException + Console.WriteLine("No conversion to an Int32 exists for the {0} value {1}.", _ + value.GetType().Name, value) + + End Try + Next + ' The example displays the following output: + ' Converted the Boolean value True to the Int32 value 1. + ' Converted the Int32 value -12 to the Int32 value -12. + ' Converted the Int32 value 163 to the Int32 value 163. + ' Converted the Int32 value 935 to the Int32 value 935. + ' Converted the Char value x to the Int32 value 120. + ' No conversion to an Int32 exists for the DateTime value 5/12/2009 12:00:00 AM. + ' Converted the String value 104 to the Int32 value 104. + ' The String value 103.0 is not in a recognizable format. + ' Converted the String value -1 to the Int32 value -1. + ' The String value 1.00e2 is not in a recognizable format. + ' The String value One is not in a recognizable format. + ' Converted the Double value 100 to the Int32 value 100. + ' The Double value 1.63E+43 is outside the range of the Int32 type. + ' + End Sub + + Private Sub ConvertSByte() + ' + Dim numbers() As SByte = { SByte.MinValue, -1, 0, 10, SByte.MaxValue } + Dim result As Integer + + For Each number As SByte In numbers + result = Convert.ToInt32(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", _ + number.GetType().Name, number, _ + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the SByte value -128 to the Int32 value -128. + ' Converted the SByte value -1 to the Int32 value -1. + ' Converted the SByte value 0 to the Int32 value 0. + ' Converted the SByte value 10 to the Int32 value 10. + ' Converted the SByte value 127 to the Int32 value 127. + ' + End Sub + + Private Sub ConvertSingle() + ' + Dim values() As Single = { Single.MinValue, -1.38e10, -1023.299, -12.98, _ + 0, 9.113e-16, 103.919, 17834.191, Single.MaxValue } + Dim result As Integer + + For Each value As Single In values + Try + result = Convert.ToInt32(value) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", _ + value.GetType().Name, value, result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("{0} is outside the range of the Int32 type.", value) + End Try + Next + ' The example displays the following output: + ' -3.40282346638529E+38 is outside the range of the Int32 type. + ' -13799999488 is outside the range of the Int32 type. + ' Converted the Double value -1023.29901123047 to the Int32 value -1023. + ' Converted the Double value -12.9799995422363 to the Int32 value -13. + ' Converted the Double value 0 to the Int32 value 0. + ' Converted the Double value 9.11299983940444E-16 to the Int32 value 0. + ' Converted the Double value 103.918998718262 to the Int32 value 104. + ' Converted the Double value 17834.19140625 to the Int32 value 17834. + ' 3.40282346638529E+38 is outside the range of the Int32 type. + ' + End Sub + + Private Sub ConvertString() + ' + Dim values() As String = { "One", "1.34e28", "-26.87", "-18", "-6.00", _ + " 0", "137", "1601.9", Int32.MaxValue.ToString() } + Dim result As Integer + + For Each value As String In values + Try + result = Convert.ToInt32(value) + Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.", _ + value.GetType().Name, value, result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("{0} is outside the range of the Int32 type.", value) + Catch e As FormatException + Console.WriteLine("The {0} value '{1}' is not in a recognizable format.", _ + value.GetType().Name, value) + End Try + Next + ' The example displays the following output: + ' The String value 'One' is not in a recognizable format. + ' The String value '1.34e28' is not in a recognizable format. + ' The String value '-26.87' is not in a recognizable format. + ' Converted the String value '-18' to the Int32 value -18. + ' The String value '-6.00' is not in a recognizable format. + ' Converted the String value ' 0' to the Int32 value 0. + ' Converted the String value '137' to the Int32 value 137. + ' The String value '1601.9' is not in a recognizable format. + ' Converted the String value '2147483647' to the Int32 value 2147483647. + ' + End Sub + + Private Sub ConvertUInt16() + ' + Dim numbers() As UShort = { UInt16.MinValue, 121, 340, UInt16.MaxValue } + Dim result As Integer + For Each number As UShort In numbers + Try + result = Convert.ToInt32(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", _ + number.GetType().Name, number, _ + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.", _ + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' Converted the UInt16 value 0 to the Int32 value 0. + ' Converted the UInt16 value 121 to the Int32 value 121. + ' Converted the UInt16 value 340 to the Int32 value 340. + ' Converted the UInt16 value 65535 to the Int32 value 65535. + ' + End Sub + + Private Sub ConvertUInt32() + ' + Dim numbers() As UInteger = { UInt32.MinValue, 121, 340, UInt32.MaxValue } + Dim result As Integer + For Each number As UInteger In numbers + Try + result = Convert.ToInt32(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", _ + number.GetType().Name, number, _ + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.", _ + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' Converted the UInt32 value 0 to the Int32 value 0. + ' Converted the UInt32 value 121 to the Int32 value 121. + ' Converted the UInt32 value 340 to the Int32 value 340. + ' The UInt32 value 4294967295 is outside the range of the Int32 type. + ' + End Sub + + Private Sub ConvertUInt64 + ' + Dim numbers() As ULong = { UInt64.MinValue, 121, 340, UInt64.MaxValue } + Dim result As Integer + For Each number As ULong In numbers + Try + result = Convert.ToInt32(number) + Console.WriteLine("Converted the {0} value {1} to a {2} value {3}.", _ + number.GetType().Name, number, _ + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.", _ + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' Converted the UInt64 value 0 to a Int32 value 0. + ' Converted the UInt64 value 121 to a Int32 value 121. + ' Converted the UInt64 value 340 to a Int32 value 340. + ' The UInt64 value 18446744073709551615 is outside the range of the Int32 type. + ' + End Sub +End Module diff --git a/snippets/visualbasic/System/Convert/Overview/toint64_1.vb b/snippets/visualbasic/System/Convert/Overview/toint64_1.vb new file mode 100644 index 00000000000..307a0c4d655 --- /dev/null +++ b/snippets/visualbasic/System/Convert/Overview/toint64_1.vb @@ -0,0 +1,375 @@ +' Visual Basic .NET Document +Option Strict On + +Module modMain2 + Public Sub Main() + ConvertBoolean() + Console.WriteLine("-----") + ConvertByte() + Console.WriteLine("-----") + ConvertChar() + Console.WriteLine("-----") + ConvertDecimal() + Console.WriteLine("-----") + ConvertDouble() + Console.WriteLine("-----") + ConvertInt16() + Console.WriteLine("-----") + ConvertInt32() + Console.WriteLine("-----") + ConvertObject() + Console.WriteLine("-----") + ConvertSByte() + Console.WriteLine("-----") + ConvertSingle() + Console.WriteLine("----") + ConvertString() + Console.WriteLine("-----") + ConvertUInt16() + Console.WriteLine("-----") + ConvertUInt32() + Console.WriteLine("-----") + ConvertUInt64() + End Sub + + Private Sub ConvertBoolean() + ' + Dim falseFlag As Boolean = False + Dim trueFlag As Boolean = True + + Console.WriteLine("{0} converts to {1}.", falseFlag, + Convert.ToInt64(falseFlag)) + Console.WriteLine("{0} converts to {1}.", trueFlag, + Convert.ToInt64(trueFlag)) + ' The example displays the following output: + ' False converts to 0. + ' True converts to 1. + ' + End Sub + + Private Sub ConvertByte() + ' + Dim bytes() As Byte = {Byte.MinValue, 14, 122, Byte.MaxValue} + Dim result As Long + + For Each byteValue As Byte In bytes + result = Convert.ToInt64(byteValue) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + byteValue.GetType().Name, byteValue, + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the Byte value 0 to the Int64 value 0. + ' Converted the Byte value 14 to the Int64 value 14. + ' Converted the Byte value 122 to the Int64 value 122. + ' Converted the Byte value 255 to the Int64 value 255. + ' + End Sub + + Private Sub ConvertChar() + ' + Dim chars() As Char = {"a"c, "z"c, ChrW(7), ChrW(1023), + ChrW(Short.MaxValue), ChrW(&HFFFE)} + Dim result As Long + + For Each ch As Char In chars + result = Convert.ToInt64(ch) + Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.", + ch.GetType().Name, ch, + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the Char value 'a' to the Int64 value 97. + ' Converted the Char value 'z' to the Int64 value 122. + ' Converted the Char value '' to the Int64 value 7. + ' Converted the Char value 'Ͽ' to the Int64 value 1023. + ' Converted the Char value '翿' to the Int64 value 32767. + ' Converted the Char value '￾' to the Int64 value 65534. + ' + End Sub + + Private Sub ConvertDecimal() + ' + Dim values() As Decimal = {Decimal.MinValue, -1034.23D, -12D, 0D, 147D, + 199.55D, 9214.16D, Decimal.MaxValue} + Dim result As Long + + For Each value As Decimal In values + Try + result = Convert.ToInt64(value) + Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.", + value.GetType().Name, value, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("{0} is outside the range of the Int64 type.", + value) + End Try + Next + ' The example displays the following output: + ' -79228162514264337593543950335 is outside the range of the Int64 type. + ' Converted the Decimal value '-1034.23' to the Int64 value -1034. + ' Converted the Decimal value '-12' to the Int64 value -12. + ' Converted the Decimal value '0' to the Int64 value 0. + ' Converted the Decimal value '147' to the Int64 value 147. + ' Converted the Decimal value '199.55' to the Int64 value 200. + ' Converted the Decimal value '9214.16' to the Int64 value 9214. + ' 79228162514264337593543950335 is outside the range of the Int64 type. + ' + End Sub + + Private Sub ConvertDouble() + ' + Dim values() As Double = {Double.MinValue, -13800000000.0, -1023.299, -12.98, + 0, 0.0000000000000009113, 103.919, 17834.191, Double.MaxValue} + Dim result As Long + + For Each value As Double In values + Try + result = Convert.ToInt64(value) + Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.", + value.GetType().Name, value, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("{0} is outside the range of the Int64 type.", value) + End Try + Next + ' -1.79769313486232E+308 is outside the range of the Int64 type. + ' Converted the Double value '-13800000000' to the Int64 value -13800000000. + ' Converted the Double value '-1023.299' to the Int64 value -1023. + ' Converted the Double value '-12.98' to the Int64 value -13. + ' Converted the Double value '0' to the Int64 value 0. + ' Converted the Double value '9.113E-16' to the Int64 value 0. + ' Converted the Double value '103.919' to the Int64 value 104. + ' Converted the Double value '17834.191' to the Int64 value 17834. + ' 1.79769313486232E+308 is outside the range of the Int64 type. + ' + End Sub + + Private Sub ConvertInt16() + ' + Dim numbers() As Short = {Int16.MinValue, -1, 0, 121, 340, Int16.MaxValue} + Dim result As Long + + For Each number As Short In numbers + result = Convert.ToInt64(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the Int16 value -32768 to the Int64 value -32768. + ' Converted the Int16 value -1 to the Int64 value -1. + ' Converted the Int16 value 0 to the Int64 value 0. + ' Converted the Int16 value 121 to the Int64 value 121. + ' Converted the Int16 value 340 to the Int64 value 340. + ' Converted the Int16 value 32767 to the Int64 value 32767. + ' + End Sub + + Private Sub ConvertInt32() + ' + Dim numbers() As Integer = {Int32.MinValue, -1, 0, 121, 340, Int32.MaxValue} + Dim result As Long + For Each number As Integer In numbers + result = Convert.ToInt64(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the Int32 value -2147483648 to the Int64 value -2147483648. + ' Converted the Int32 value -1 to the Int64 value -1. + ' Converted the Int32 value 0 to the Int64 value 0. + ' Converted the Int32 value 121 to the Int64 value 121. + ' Converted the Int32 value 340 to the Int64 value 340. + ' Converted the Int32 value 2147483647 to the Int64 value 2147483647. + ' + End Sub + + Private Sub ConvertObject() + ' + Dim values() As Object = {True, -12, 163, 935, "x"c, #5/12/2009#, + "104", "103.0", "-1", + "1.00e2", "One", 100.0, 1.63E+43} + Dim result As Long + + For Each value As Object In values + Try + result = Convert.ToInt64(value) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + value.GetType().Name, value, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Int64 type.", + value.GetType().Name, value) + Catch e As FormatException + Console.WriteLine("The {0} value {1} is not in a recognizable format.", + value.GetType().Name, value) + Catch e As InvalidCastException + Console.WriteLine("No conversion to an Int64 exists for the {0} value {1}.", + value.GetType().Name, value) + + End Try + Next + ' The example displays the following output: + ' Converted the Boolean value True to the Int64 value 1. + ' Converted the Int64 value -12 to the Int64 value -12. + ' Converted the Int64 value 163 to the Int64 value 163. + ' Converted the Int64 value 935 to the Int64 value 935. + ' Converted the Char value x to the Int64 value 120. + ' No conversion to an Int64 exists for the DateTime value 5/12/2009 12:00:00 AM. + ' Converted the String value 104 to the Int64 value 104. + ' The String value 103.0 is not in a recognizable format. + ' Converted the String value -1 to the Int64 value -1. + ' The String value 1.00e2 is not in a recognizable format. + ' The String value One is not in a recognizable format. + ' Converted the Double value 100 to the Int64 value 100. + ' The Double value 1.63E+43 is outside the range of the Int64 type. + ' + End Sub + + Private Sub ConvertSByte() + ' + Dim numbers() As SByte = {SByte.MinValue, -1, 0, 10, SByte.MaxValue} + Dim result As Long + + For Each number As SByte In numbers + result = Convert.ToInt64(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the SByte value -128 to the Int64 value -128. + ' Converted the SByte value -1 to the Int64 value -1. + ' Converted the SByte value 0 to the Int64 value 0. + ' Converted the SByte value 10 to the Int64 value 10. + ' Converted the SByte value 127 to the Int64 value 127. + ' + End Sub + + Private Sub ConvertSingle() + ' + Dim values() As Single = {Single.MinValue, -13800000000.0, -1023.299, -12.98, + 0, 0.0000000000000009113, 103.919, 17834.191, Single.MaxValue} + Dim result As Long + + For Each value As Single In values + Try + result = Convert.ToInt64(value) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + value.GetType().Name, value, result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("{0} is outside the range of the Int64 type.", value) + End Try + Next + ' The example displays the following output: + ' -3.4028235E+38 is outside the range of the Int64 type. + ' Converted the Single value -1.38E+10 to the Int64 value -13799999488. + ' Converted the Single value -1023.299 to the Int64 value -1023. + ' Converted the Single value -12.98 to the Int64 value -13. + ' Converted the Single value 0 to the Int64 value 0. + ' Converted the Single value 9.113E-16 to the Int64 value 0. + ' Converted the Single value 103.919 to the Int64 value 104. + ' Converted the Single value 17834.191 to the Int64 value 17834. + ' 3.4028235E+38 is outside the range of the Int64 type. + ' + End Sub + + Private Sub ConvertString() + ' + Dim values() As String = {"One", "1.34e28", "-26.87", "-18", "-6.00", + " 0", "137", "1601.9", Int32.MaxValue.ToString()} + Dim result As Long + + For Each value As String In values + Try + result = Convert.ToInt64(value) + Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.", + value.GetType().Name, value, result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("{0} is outside the range of the Int64 type.", value) + Catch e As FormatException + Console.WriteLine("The {0} value '{1}' is not in a recognizable format.", + value.GetType().Name, value) + End Try + Next + ' The example displays the following output: + ' The String value 'One' is not in a recognizable format. + ' The String value '1.34e28' is not in a recognizable format. + ' The String value '-26.87' is not in a recognizable format. + ' Converted the String value '-18' to the Int64 value -18. + ' The String value '-6.00' is not in a recognizable format. + ' Converted the String value ' 0' to the Int64 value 0. + ' Converted the String value '137' to the Int64 value 137. + ' The String value '1601.9' is not in a recognizable format. + ' Converted the String value '2147483647' to the Int64 value 2147483647. + ' + End Sub + + Private Sub ConvertUInt16() + ' + Dim numbers() As UShort = {UInt16.MinValue, 121, 340, UInt16.MaxValue} + Dim result As Long + For Each number As UShort In numbers + Try + result = Convert.ToInt64(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Int64 type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' Converted the UInt16 value 0 to the Int64 value 0. + ' Converted the UInt16 value 121 to the Int64 value 121. + ' Converted the UInt16 value 340 to the Int64 value 340. + ' Converted the UInt16 value 65535 to the Int64 value 65535. + ' + End Sub + + Private Sub ConvertUInt32() + ' + Dim numbers() As UInteger = {UInt32.MinValue, 121, 340, UInt32.MaxValue} + Dim result As Long + For Each number As UInteger In numbers + result = Convert.ToInt64(number) + Console.WriteLine("Converted the {0} value {1:N0} to the {2} value {3:N0}.", + number.GetType().Name, number, + result.GetType().Name, result) + Next + ' The example displays the following output: + ' Converted the UInt32 value 0 to the Int64 value 0. + ' Converted the UInt32 value 121 to the Int64 value 121. + ' Converted the UInt32 value 340 to the Int64 value 340. + ' Converted the UInt32 value 4,294,967,295 to the Int64 value 4,294,967,295. + ' + End Sub + + Private Sub ConvertUInt64() + ' + Dim numbers() As ULong = {UInt64.MinValue, 121, 340, UInt64.MaxValue} + Dim result As Long + + For Each number As ULong In numbers + Try + result = Convert.ToInt64(number) + Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", + number.GetType().Name, number, + result.GetType().Name, result) + Catch e As OverflowException + Console.WriteLine("The {0} value {1} is outside the range of the Int64 type.", + number.GetType().Name, number) + End Try + Next + ' The example displays the following output: + ' Converted the UInt64 value 0 to the Int64 value 0. + ' Converted the UInt64 value 121 to the Int64 value 121. + ' Converted the UInt64 value 340 to the Int64 value 340. + ' The UInt64 value 18446744073709551615 is outside the range of the Int64 type. + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/DateTime/FromBinary/Project.vbproj b/snippets/visualbasic/System/DateTime/FromBinary/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/DateTime/FromBinary/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/DateTime/FromBinary/frombinary1.vb b/snippets/visualbasic/System/DateTime/FromBinary/frombinary1.vb new file mode 100644 index 00000000000..1f0f3e918e7 --- /dev/null +++ b/snippets/visualbasic/System/DateTime/FromBinary/frombinary1.vb @@ -0,0 +1,22 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example + Public Sub Main() + Dim localDate As Date = DateTime.SpecifyKind(#03/14/2010 2:30AM#, DateTimeKind.Local) + Dim binLocal As Long = localDate.ToBinary() + If TimeZoneInfo.Local.IsInvalidTime(localDate) Then + Console.WriteLine("{0} is an invalid time in the {1} zone.", _ + localDate, _ + TimeZoneInfo.Local.StandardName) + End If + Dim localDate2 As Date = DateTime.FromBinary(binLocal) + Console.WriteLine("{0} = {1}: {2}", _ + localDate, localDate2, localDate.Equals(localDate2)) + End Sub +End Module +' The example displays the following output: +' 3/14/2010 2:30:00 AM is an invalid time in the Pacific Standard Time zone. +' 3/14/2010 2:30:00 AM = 3/14/2010 3:30:00 AM: False +' diff --git a/snippets/visualbasic/System/DateTime/Overview/Calendar.vb b/snippets/visualbasic/System/DateTime/Overview/Calendar.vb new file mode 100644 index 00000000000..23346c6863c --- /dev/null +++ b/snippets/visualbasic/System/DateTime/Overview/Calendar.vb @@ -0,0 +1,110 @@ +Imports System.Globalization + +Module CalendarSamples + Public Sub Snippets() + ThaiBuddhistEra() + ThaiBuddhistEraParse() + InstantiateCalendar() + CalendarFields() + CalculateWeeks() + End Sub + + Private Sub ThaiBuddhistEra() + ' + Dim thTH As New CultureInfo("th-TH") + Dim value As New DateTime(2016, 5, 28) + + Console.WriteLine(value.ToString(thTH)) + + thTH.DateTimeFormat.Calendar = New GregorianCalendar() + Console.WriteLine(value.ToString(thTH)) + ' The example displays the following output: + ' 28/5/2559 0:00:00 + ' 28/5/2016 0:00:00 + ' + End Sub + + ' + Private Sub ThaiBuddhistEraParse() + Dim thTH As New CultureInfo("th-TH") + Dim value As DateTime = DateTime.Parse("28/5/2559", thTH) + Console.WriteLine(value.ToString(thTH)) + + thTH.DateTimeFormat.Calendar = New GregorianCalendar() + Console.WriteLine(value.ToString(thTH)) + ' The example displays the following output: + ' 28/5/2559 0:00:00 + ' 28/5/2016 0:00:00 + End Sub + ' + + Private Sub InstantiateCalendar() + ' + Dim thTH As New CultureInfo("th-TH") + Dim dat As New DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar) + Console.WriteLine($"Thai Buddhist Era date: {dat.ToString("d", thTH)}") + Console.WriteLine($"Gregorian date: {dat:d}") + ' The example displays the following output: + ' Thai Buddhist Era Date: 28/5/2559 + ' Gregorian Date: 28/05/2016 + ' + End Sub + + Private Sub CalendarFields() + ' + Dim thTH As New CultureInfo("th-TH") + Dim cal As Calendar = thTH.DateTimeFormat.Calendar + Dim dat As New DateTime(2559, 5, 28, cal) + Console.WriteLine("Using the Thai Buddhist Era calendar:") + Console.WriteLine($"Date: {dat.ToString("d", thTH)}") + Console.WriteLine($"Year: {cal.GetYear(dat)}") + Console.WriteLine($"Leap year: {cal.IsLeapYear(cal.GetYear(dat))}") + Console.WriteLine() + + Console.WriteLine("Using the Gregorian calendar:") + Console.WriteLine($"Date: {dat:d}") + Console.WriteLine($"Year: {dat.Year}") + Console.WriteLine($"Leap year: {DateTime.IsLeapYear(dat.Year)}") + ' The example displays the following output: + ' Using the Thai Buddhist Era calendar + ' Date : 28/5/2559 + ' Year: 2559 + ' Leap year : True + ' + ' Using the Gregorian calendar + ' Date : 28/05/2016 + ' Year: 2016 + ' Leap year : True + ' + End Sub + + Private Sub CalculateWeeks() + ' + Dim thTH As New CultureInfo("th-TH") + Dim thCalendar As Calendar = thTH.DateTimeFormat.Calendar + Dim dat As New DateTime(1395, 8, 18, thCalendar) + Console.WriteLine("Using the Thai Buddhist Era calendar:") + Console.WriteLine($"Date: {dat.ToString("d", thTH)}") + Console.WriteLine($"Day of Week: {thCalendar.GetDayOfWeek(dat)}") + Console.WriteLine($"Week of year: {thCalendar.GetWeekOfYear(dat, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}") + Console.WriteLine() + + Dim greg As Calendar = New GregorianCalendar() + Console.WriteLine("Using the Gregorian calendar:") + Console.WriteLine($"Date: {dat:d}") + Console.WriteLine($"Day of Week: {dat.DayOfWeek}") + Console.WriteLine($"Week of year: {greg.GetWeekOfYear(dat, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}") + ' The example displays the following output: + ' Using the Thai Buddhist Era calendar + ' Date : 18/8/1395 + ' Day of Week: Sunday + ' Week of year: 34 + ' + ' Using the Gregorian calendar + ' Date : 18/08/0852 + ' Day of Week: Sunday + ' Week of year: 34 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/DateTime/Overview/DateTimeComparisons.vb b/snippets/visualbasic/System/DateTime/Overview/DateTimeComparisons.vb new file mode 100644 index 00000000000..aee488bf948 --- /dev/null +++ b/snippets/visualbasic/System/DateTime/Overview/DateTimeComparisons.vb @@ -0,0 +1,58 @@ +Class DateTimeComparisons + Public Shared Sub Snippets() + TestRoughlyEquals() + End Sub + + ' + Public Shared Function RoughlyEquals(time As DateTime, timeWithWindow As DateTime, + windowInSeconds As Integer, + frequencyInSeconds As Integer) As Boolean + Dim delta As Long = (timeWithWindow.Subtract(time)).TotalSeconds _ + Mod frequencyInSeconds + + If delta > windowInSeconds Then + delta = frequencyInSeconds - delta + End If + + Return Math.Abs(delta) < windowInSeconds + End Function + + Public Shared Sub TestRoughlyEquals() + Dim window As Integer = 10 + Dim freq As Integer = 60 * 60 * 2 ' 2 hours; + Dim d1 As DateTime = DateTime.Now + + Dim d2 As DateTime = d1.AddSeconds(2 * window) + Dim d3 As DateTime = d1.AddSeconds(-2 * window) + Dim d4 As DateTime = d1.AddSeconds(window / 2) + Dim d5 As DateTime = d1.AddSeconds(-window / 2) + + Dim d6 As DateTime = d1.AddHours(2).AddSeconds(2 * window) + Dim d7 As DateTime = d1.AddHours(2).AddSeconds(-2 * window) + Dim d8 As DateTime = d1.AddHours(2).AddSeconds(window / 2) + Dim d9 As DateTime = d1.AddHours(2).AddSeconds(-window / 2) + + Console.WriteLine($"d1 ({d1}) ~= d1 ({d1}): {RoughlyEquals(d1, d1, window, freq)}") + Console.WriteLine($"d1 ({d1}) ~= d2 ({d2}): {RoughlyEquals(d1, d2, window, freq)}") + Console.WriteLine($"d1 ({d1}) ~= d3 ({d3}): {RoughlyEquals(d1, d3, window, freq)}") + Console.WriteLine($"d1 ({d1}) ~= d4 ({d4}): {RoughlyEquals(d1, d4, window, freq)}") + Console.WriteLine($"d1 ({d1}) ~= d5 ({d5}): {RoughlyEquals(d1, d5, window, freq)}") + + Console.WriteLine($"d1 ({d1}) ~= d6 ({d6}): {RoughlyEquals(d1, d6, window, freq)}") + Console.WriteLine($"d1 ({d1}) ~= d7 ({d7}): {RoughlyEquals(d1, d7, window, freq)}") + Console.WriteLine($"d1 ({d1}) ~= d8 ({d8}): {RoughlyEquals(d1, d8, window, freq)}") + Console.WriteLine($"d1 ({d1}) ~= d9 ({d9}): {RoughlyEquals(d1, d9, window, freq)}") + End Sub + ' The example displays output similar to the following: + ' d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True + ' d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False + ' d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False + ' d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True + ' d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True + ' d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False + ' d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False + ' d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True + ' d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True + ' + +End Class diff --git a/snippets/visualbasic/System/DateTime/Overview/Instantiation.vb b/snippets/visualbasic/System/DateTime/Overview/Instantiation.vb new file mode 100644 index 00000000000..b4612342cd9 --- /dev/null +++ b/snippets/visualbasic/System/DateTime/Overview/Instantiation.vb @@ -0,0 +1,61 @@ +Module Instantiation + + Public Sub Snippets() + InstantiateWithConstructor() + InstantiateWithCompilerSyntax() + InstantiateWithReturnValue() + InstantiateFromString() + InstantiateUsingDftCtor() + End Sub + + Private Sub InstantiateWithConstructor() + ' + Dim date1 As New Date(2008, 5, 1, 8, 30, 52) + ' + End Sub + + Private Sub InstantiateWithCompilerSyntax() + ' + Dim date1 As Date = #5/1/2008 8:30:52AM# + ' + End Sub + + Private Sub InstantiateWithReturnValue() + ' + Dim date1 As Date = Date.Now + Dim date2 As Date = Date.UtcNow + Dim date3 As Date = Date.Today + ' + End Sub + + Private Sub InstantiateFromString() + ' + Dim dateString As String = "5/1/2008 8:30:52 AM" + Dim date1 As Date = Date.Parse(dateString, + System.Globalization.CultureInfo.InvariantCulture) + Dim iso8601String As String = "20080501T08:30:52Z" + Dim dateISO8602 As Date = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", + System.Globalization.CultureInfo.InvariantCulture) + Console.WriteLine(dateISO8602) + + ' + Console.WriteLine(date1) + End Sub + + Private Sub InstantiateUsingDftCtor() + ' + Dim dat1 As DateTime + ' The following method call displays 1/1/0001 12:00:00 AM. + Console.WriteLine(dat1.ToString(System.Globalization.CultureInfo.InvariantCulture)) + ' The following method call displays True. + Console.WriteLine(dat1.Equals(Date.MinValue)) + + Dim dat2 As New DateTime() + ' The following method call displays 1/1/0001 12:00:00 AM. + Console.WriteLine(dat2.ToString(System.Globalization.CultureInfo.InvariantCulture)) + ' The following method call displays True. + Console.WriteLine(dat2.Equals(Date.MinValue)) + ' + End Sub + +End Module diff --git a/snippets/visualbasic/System/DateTime/Overview/Parsing.vb b/snippets/visualbasic/System/DateTime/Overview/Parsing.vb new file mode 100644 index 00000000000..4cfe6eecb6c --- /dev/null +++ b/snippets/visualbasic/System/DateTime/Overview/Parsing.vb @@ -0,0 +1,166 @@ +Imports System.Globalization +Imports System.Threading + +Module Parsing + Public Sub Snippets() + ParseStandardFormats() + End Sub + + Private Sub ParseStandardFormats() + ' + Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB") + + Dim date1 As New DateTime(2013, 6, 1, 12, 32, 30) + Dim badFormats As New List(Of String) + + Console.WriteLine($"{"Date String",-37} {"Date",-19}") + Console.WriteLine() + For Each dateString As String In date1.GetDateTimeFormats() + Dim parsedDate As DateTime + If DateTime.TryParse(dateString, parsedDate) Then + Console.WriteLine($"{dateString,-37} {DateTime.Parse(dateString),-19:g}") + Else + badFormats.Add(dateString) + End If + Next + + ' Display strings that could not be parsed. + If badFormats.Count > 0 Then + Console.WriteLine() + Console.WriteLine("Strings that could not be parsed: ") + For Each badFormat In badFormats + Console.WriteLine($" {badFormat}") + Next + End If + ' The example displays the following output: + ' Date String Date + ' + ' 01/06/2013 01/06/2013 00:00:00 + ' 01/06/13 01/06/2013 00:00:00 + ' 1/6/13 01/06/2013 00:00:00 + ' 1.6.13 01/06/2013 00:00:00 + ' 2013-06-01 01/06/2013 00:00:00 + ' 01 June 2013 01/06/2013 00:00:00 + ' 1 June 2013 01/06/2013 00:00:00 + ' 01 June 2013 12:32 01/06/2013 12:32:00 + ' 01 June 2013 12:32 01/06/2013 12:32:00 + ' 01 June 2013 12:32 PM 01/06/2013 12:32:00 + ' 01 June 2013 12:32 PM 01/06/2013 12:32:00 + ' 1 June 2013 12:32 01/06/2013 12:32:00 + ' 1 June 2013 12:32 01/06/2013 12:32:00 + ' 1 June 2013 12:32 PM 01/06/2013 12:32:00 + ' 1 June 2013 12:32 PM 01/06/2013 12:32:00 + ' 01 June 2013 12:32:30 01/06/2013 12:32:30 + ' 01 June 2013 12:32:30 01/06/2013 12:32:30 + ' 01 June 2013 12:32:30 PM 01/06/2013 12:32:30 + ' 01 June 2013 12:32:30 PM 01/06/2013 12:32:30 + ' 1 June 2013 12:32:30 01/06/2013 12:32:30 + ' 1 June 2013 12:32:30 01/06/2013 12:32:30 + ' 1 June 2013 12:32:30 PM 01/06/2013 12:32:30 + ' 1 June 2013 12:32:30 PM 01/06/2013 12:32:30 + ' 01/06/2013 12:32 01/06/2013 12:32:00 + ' 01/06/2013 12:32 01/06/2013 12:32:00 + ' 01/06/2013 12:32 PM 01/06/2013 12:32:00 + ' 01/06/2013 12:32 PM 01/06/2013 12:32:00 + ' 01/06/13 12:32 01/06/2013 12:32:00 + ' 01/06/13 12:32 01/06/2013 12:32:00 + ' 01/06/13 12:32 PM 01/06/2013 12:32:00 + ' 01/06/13 12:32 PM 01/06/2013 12:32:00 + ' 1/6/13 12:32 01/06/2013 12:32:00 + ' 1/6/13 12:32 01/06/2013 12:32:00 + ' 1/6/13 12:32 PM 01/06/2013 12:32:00 + ' 1/6/13 12:32 PM 01/06/2013 12:32:00 + ' 1.6.13 12:32 01/06/2013 12:32:00 + ' 1.6.13 12:32 01/06/2013 12:32:00 + ' 1.6.13 12:32 PM 01/06/2013 12:32:00 + ' 1.6.13 12:32 PM 01/06/2013 12:32:00 + ' 2013-06-01 12:32 01/06/2013 12:32:00 + ' 2013-06-01 12:32 01/06/2013 12:32:00 + ' 2013-06-01 12:32 PM 01/06/2013 12:32:00 + ' 2013-06-01 12:32 PM 01/06/2013 12:32:00 + ' 01/06/2013 12:32:30 01/06/2013 12:32:30 + ' 01/06/2013 12:32:30 01/06/2013 12:32:30 + ' 01/06/2013 12:32:30 PM 01/06/2013 12:32:30 + ' 01/06/2013 12:32:30 PM 01/06/2013 12:32:30 + ' 01/06/13 12:32:30 01/06/2013 12:32:30 + ' 01/06/13 12:32:30 01/06/2013 12:32:30 + ' 01/06/13 12:32:30 PM 01/06/2013 12:32:30 + ' 01/06/13 12:32:30 PM 01/06/2013 12:32:30 + ' 1/6/13 12:32:30 01/06/2013 12:32:30 + ' 1/6/13 12:32:30 01/06/2013 12:32:30 + ' 1/6/13 12:32:30 PM 01/06/2013 12:32:30 + ' 1/6/13 12:32:30 PM 01/06/2013 12:32:30 + ' 1.6.13 12:32:30 01/06/2013 12:32:30 + ' 1.6.13 12:32:30 01/06/2013 12:32:30 + ' 1.6.13 12:32:30 PM 01/06/2013 12:32:30 + ' 1.6.13 12:32:30 PM 01/06/2013 12:32:30 + ' 2013-06-01 12:32:30 01/06/2013 12:32:30 + ' 2013-06-01 12:32:30 01/06/2013 12:32:30 + ' 2013-06-01 12:32:30 PM 01/06/2013 12:32:30 + ' 2013-06-01 12:32:30 PM 01/06/2013 12:32:30 + ' 01 June 01/06/2013 00:00:00 + ' 01 June 01/06/2013 00:00:00 + ' 2013-06-01T12:32:30.0000000 01/06/2013 12:32:30 + ' 2013-06-01T12:32:30.0000000 01/06/2013 12:32:30 + ' Sat, 01 Jun 2013 12:32:30 GMT 01/06/2013 05:32:30 + ' Sat, 01 Jun 2013 12:32:30 GMT 01/06/2013 05:32:30 + ' 2013-06-01T12:32:30 01/06/2013 12:32:30 + ' 12:32 22/04/2013 12:32:00 + ' 12:32 22/04/2013 12:32:00 + ' 12:32 PM 22/04/2013 12:32:00 + ' 12:32 PM 22/04/2013 12:32:00 + ' 12:32:30 22/04/2013 12:32:30 + ' 12:32:30 22/04/2013 12:32:30 + ' 12:32:30 PM 22/04/2013 12:32:30 + ' 12:32:30 PM 22/04/2013 12:32:30 + ' 2013-06-01 12:32:30Z 01/06/2013 05:32:30 + ' 01 June 2013 19:32:30 01/06/2013 19:32:30 + ' 01 June 2013 19:32:30 01/06/2013 19:32:30 + ' 01 June 2013 07:32:30 PM 01/06/2013 19:32:30 + ' 01 June 2013 7:32:30 PM 01/06/2013 19:32:30 + ' 1 June 2013 19:32:30 01/06/2013 19:32:30 + ' 1 June 2013 19:32:30 01/06/2013 19:32:30 + ' 1 June 2013 07:32:30 PM 01/06/2013 19:32:30 + ' 1 June 2013 7:32:30 PM 01/06/2013 19:32:30 + ' June 2013 01/06/2013 00:00:00 + ' June 2013 01/06/2013 00:00:00 + ' + End Sub + + Private Sub ParseCustomFormats() + ' + Dim formats() As String = {"yyyyMMdd", "HHmmss"} + Dim dateStrings() As String = {"20130816", "20131608", + " 20130816 ", "115216", + "521116", " 115216 "} + Dim parsedDate As DateTime + + For Each dateString As String In dateStrings + If DateTime.TryParseExact(dateString, formats, Nothing, + DateTimeStyles.AllowWhiteSpaces Or + DateTimeStyles.AdjustToUniversal, + parsedDate) Then + Console.WriteLine($"{dateString} --> {parsedDate:g}") + Else + Console.WriteLine($"Cannot convert {dateString}") + End If + Next + ' The example displays the following output: + ' 20130816 --> 8/16/2013 12:00 AM + ' Cannot convert 20131608 + ' 20130816 --> 8/16/2013 12:00 AM + ' 115216 --> 4/22/2013 11:52 AM + ' Cannot convert 521116 + ' 115216 --> 4/22/2013 11:52 AM + ' + End Sub + + Private Sub ParseISO8601() + ' + Dim iso8601String As String = "20080501T08:30:52Z" + Dim dateISO8602 As DateTime = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", CultureInfo.InvariantCulture) + Console.WriteLine($"{iso8601String} --> {dateISO8602:g}") + ' + + End Sub +End Module diff --git a/snippets/visualbasic/System/DateTime/Overview/Project.vbproj b/snippets/visualbasic/System/DateTime/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/DateTime/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/DateTime/Overview/Resolution.vb b/snippets/visualbasic/System/DateTime/Overview/Resolution.vb new file mode 100644 index 00000000000..a317d56fe09 --- /dev/null +++ b/snippets/visualbasic/System/DateTime/Overview/Resolution.vb @@ -0,0 +1,50 @@ +Imports System.Threading + +Module Resolution + + Public Sub Snippets() + DemonstrateResolution() + End Sub + + Private Sub DemonstrateResolution() + ' + Dim output As String = "" + For ctr As Integer = 0 To 20 + output += Date.Now.Millisecond.ToString() + vbCrLf + ' Introduce a delay loop. + For delay As Integer = 0 To 1000 + Next + + If ctr = 10 Then + output += "Thread.Sleep called..." + vbCrLf + Thread.Sleep(5) + End If + Next + Console.WriteLine(output) + ' The example displays output like the following: + ' 111 + ' 111 + ' 111 + ' 111 + ' 111 + ' 111 + ' 111 + ' 111 + ' 111 + ' 111 + ' 111 + ' Thread.Sleep called... + ' 143 + ' 143 + ' 143 + ' 143 + ' 143 + ' 143 + ' 143 + ' 143 + ' 143 + ' 143 + ' + + End Sub +End Module diff --git a/snippets/visualbasic/System/DateTime/Overview/StringFormat.vb b/snippets/visualbasic/System/DateTime/Overview/StringFormat.vb new file mode 100644 index 00000000000..9d488e4f41f --- /dev/null +++ b/snippets/visualbasic/System/DateTime/Overview/StringFormat.vb @@ -0,0 +1,50 @@ +Module StringFormat + Public Sub Snippets() + ShowDefaultToString() + ShowCultureSpecificToString() + ShowDefaultFullDateAndTime() + ShowCultureSpecificFullDateAndTime() + ShowIsoDateTime() + End Sub + + Private Sub ShowDefaultToString() + ' + Dim date1 As Date = #3/1/2008 7:00AM# + Console.WriteLine(date1.ToString()) + ' For en-US culture, displays 3/1/2008 7:00:00 AM + ' + End Sub + + Private Sub ShowCultureSpecificToString() + ' + Dim date1 As Date = #3/1/2008 7:00AM# + Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR"))) + ' Displays 01/03/2008 07:00:00 + ' + End Sub + + Private Sub ShowDefaultFullDateAndTime() + ' + Dim date1 As Date = #3/1/2008 7:00AM# + Console.WriteLine(date1.ToString("F")) + ' Displays Saturday, March 01, 2008 7:00:00 AM + ' + End Sub + + Private Sub ShowCultureSpecificFullDateAndTime() + ' + Dim date1 As Date = #3/1/2008 7:00AM# + Console.WriteLine(date1.ToString("F", New System.Globalization.CultureInfo("fr-FR"))) + ' Displays samedi 1 mars 2008 07:00:00 + ' + End Sub + + Private Sub ShowIsoDateTime() + ' + Dim date1 As DateTime = New DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc) + Console.WriteLine(date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture)) + ' Displays 2008-03-01T07:00:00+00:00 + ' + End Sub + +End Module diff --git a/snippets/visualbasic/System/Decimal/Overview/DecimalDivision_46630_1.vb b/snippets/visualbasic/System/Decimal/Overview/DecimalDivision_46630_1.vb new file mode 100644 index 00000000000..4adba2f5bbc --- /dev/null +++ b/snippets/visualbasic/System/Decimal/Overview/DecimalDivision_46630_1.vb @@ -0,0 +1,47 @@ +' Visual Basic .NET Document +Option Strict On + +Module modMain + + Public Sub Main() + DivideWithSingles() + DivideWithDoubles() + DivideWithoutRounding() + DivideWithRounding() + End Sub + + Private Sub DivideWithoutRounding() + Console.WriteLine("DivideWithoutRounding") + ' + Dim dividend As Decimal = Decimal.One + Dim divisor As Decimal = 3 + ' The following displays 0.9999999999999999999999999999 to the console + Console.WriteLine(dividend/divisor * divisor) + ' + End Sub + + Private Sub DivideWithRounding() + Console.WriteLine("DivideWithRounding") + ' + Dim dividend As Decimal = Decimal.One + Dim divisor As Decimal = 3 + ' The following displays 1.00 to the console + Console.WriteLine(Math.Round(dividend/divisor * divisor, 2)) + ' + End Sub + + Private Sub DivideWithSingles() + Console.WriteLine("DivideWithSingles") + Dim dividend As Single = 1 + Dim divisor As Single = 3 + Console.WriteLine(dividend/divisor * divisor) + End Sub + + Private Sub DivideWithDoubles() + Console.WriteLine("DivideWithDoubles") + Dim dividend As Double = 1 + Dim divisor As Double = 3 + Console.WriteLine(dividend/divisor * divisor) + End Sub +End Module + diff --git a/snippets/visualbasic/System/Decimal/Overview/Project.vbproj b/snippets/visualbasic/System/Decimal/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Decimal/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Decimal/Overview/source.vb b/snippets/visualbasic/System/Decimal/Overview/source.vb new file mode 100644 index 00000000000..59430b7e607 --- /dev/null +++ b/snippets/visualbasic/System/Decimal/Overview/source.vb @@ -0,0 +1,122 @@ +Namespace Snippets + Class Launcher + 'Entry point which delegates to C-style main Private Function + Public Overloads Shared Sub Main() + Dim pb As New PiggyBank() + + Dim i As Integer + For i = 0 To 377 + pb.AddPenny() + Next i + + Console.WriteLine(pb) + + Console.ReadLine() + End Sub + End Class + + ' + ' Keeping my fortune in Decimals to avoid the round-off errors. + Class PiggyBank + Protected MyFortune As Decimal + + Public Sub AddPenny() + MyFortune = [Decimal].Add(MyFortune, 0.01D) + End Sub + + Public ReadOnly Property Capacity() As Decimal + Get + Return [Decimal].MaxValue + End Get + End Property + + Public ReadOnly Property Dollars() As Decimal + Get + Return [Decimal].Floor(MyFortune) + End Get + End Property + + Public ReadOnly Property Cents() As Decimal + Get + Return [Decimal].Subtract(MyFortune, [Decimal].Floor(MyFortune)) + End Get + End Property + + Public Overrides Function ToString() As String + Return MyFortune.ToString("C") + " in piggy bank" + End Function + End Class + ' +End Namespace + +Namespace Snippets2 + ' + Class PiggyBank + Public ReadOnly Property Capacity() As Decimal + Get + Return [Decimal].MaxValue + End Get + End Property + + Protected MyFortune As Decimal + + Public Sub AddPenny() + MyFortune += 0.01D + End Sub + End Class + ' +End Namespace + +Namespace Snippets3 + ' + Class PiggyBank + Public ReadOnly Property Dollars() As Decimal + Get + Return [Decimal].Floor(MyFortune) + End Get + End Property + + Protected MyFortune As Decimal + + Public Sub AddPenny() + MyFortune += 0.01D + End Sub + End Class + ' +End Namespace + +Namespace Snippets4 + _ + ' + Class PiggyBank + Public ReadOnly Property Cents() As Decimal + Get + Return [Decimal].Subtract(MyFortune, [Decimal].Floor(MyFortune)) + End Get + End Property + + Protected MyFortune As Decimal + + Public Sub AddPenny() + MyFortune += 0.01D + End Sub + End Class + ' +End Namespace + +Namespace Snippets5 + ' + Class PiggyBank + + Public Sub AddPenny() + MyFortune = [Decimal].Add(MyFortune, 0.01D) + End Sub + + Public Overrides Function ToString() As String + Return MyFortune.ToString("C") + " in piggy bank" + End Function + + Protected MyFortune As Decimal + End Class + ' +End Namespace diff --git a/snippets/visualbasic/System/Delegate/CreateDelegate/Project.vbproj b/snippets/visualbasic/System/Delegate/CreateDelegate/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Delegate/CreateDelegate/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Delegate/CreateDelegate/openClosedOver.vb b/snippets/visualbasic/System/Delegate/CreateDelegate/openClosedOver.vb new file mode 100644 index 00000000000..797ff36a1e1 --- /dev/null +++ b/snippets/visualbasic/System/Delegate/CreateDelegate/openClosedOver.vb @@ -0,0 +1,137 @@ +' All four permutations of instance/Shared with open/closed. +' +' +Imports System.Reflection +Imports System.Security.Permissions + +' Declare three delegate types for demonstrating the combinations +' of Shared versus instance methods and open versus closed +' delegates. +' +Public Delegate Sub D1(ByVal c As C2, ByVal s As String) +Public Delegate Sub D2(ByVal s As String) +Public Delegate Sub D3() + +' A sample class with an instance method and a Shared method. +' +Public Class C2 + Private id As Integer + Public Sub New(ByVal id As Integer) + Me.id = id + End Sub + + Public Sub M1(ByVal s As String) + Console.WriteLine("Instance method M1 on C2: id = {0}, s = {1}", + Me.id, s) + End Sub + + Public Shared Sub M2(ByVal s As String) + Console.WriteLine("Shared method M2 on C2: s = {0}", s) + End Sub +End Class + +Public Class Example2 + + Public Shared Sub Main() + + Dim c1 As New C2(42) + + ' Get a MethodInfo for each method. + ' + Dim mi1 As MethodInfo = GetType(C2).GetMethod("M1", + BindingFlags.Public Or BindingFlags.Instance) + Dim mi2 As MethodInfo = GetType(C2).GetMethod("M2", + BindingFlags.Public Or BindingFlags.Static) + + Dim d1 As D1 + Dim d2 As D2 + Dim d3 As D3 + + + Console.WriteLine(vbLf & "An instance method closed over C2.") + ' In this case, the delegate and the + ' method must have the same list of argument types; use + ' delegate type D2 with instance method M1. + ' + Dim test As [Delegate] = + [Delegate].CreateDelegate(GetType(D2), c1, mi1, False) + + ' Because False was specified for throwOnBindFailure + ' in the call to CreateDelegate, the variable 'test' + ' contains Nothing if the method fails to bind (for + ' example, if mi1 happened to represent a method of + ' some class other than C2). + ' + If test IsNot Nothing Then + d2 = CType(test, D2) + + ' The same instance of C2 is used every time the + ' delegate is invoked. + d2("Hello, World!") + d2("Hi, Mom!") + End If + + + Console.WriteLine(vbLf & "An open instance method.") + ' In this case, the delegate has one more + ' argument than the instance method; this argument comes + ' at the beginning, and represents the hidden instance + ' argument of the instance method. Use delegate type D1 + ' with instance method M1. + ' + d1 = CType([Delegate].CreateDelegate(GetType(D1), Nothing, mi1), D1) + + ' An instance of C2 must be passed in each time the + ' delegate is invoked. + ' + d1(c1, "Hello, World!") + d1(New C2(5280), "Hi, Mom!") + + + Console.WriteLine(vbLf & "An open Shared method.") + ' In this case, the delegate and the method must + ' have the same list of argument types; use delegate type + ' D2 with Shared method M2. + ' + d2 = CType([Delegate].CreateDelegate(GetType(D2), Nothing, mi2), D2) + + ' No instances of C2 are involved, because this is a Shared + ' method. + ' + d2("Hello, World!") + d2("Hi, Mom!") + + + Console.WriteLine(vbLf & "A Shared method closed over the first argument (String).") + ' The delegate must omit the first argument of the method. + ' A string is passed as the firstArgument parameter, and + ' the delegate is bound to this string. Use delegate type + ' D3 with Shared method M2. + ' + d3 = CType([Delegate].CreateDelegate(GetType(D3), "Hello, World!", mi2), D3) + + ' Each time the delegate is invoked, the same string is + ' used. + d3() + + End Sub +End Class + +' This code example produces the following output: +' +'An instance method closed over C2. +'Instance method M1 on C2: id = 42, s = Hello, World! +'Instance method M1 on C2: id = 42, s = Hi, Mom! +' +'An open instance method. +'Instance method M1 on C2: id = 42, s = Hello, World! +'Instance method M1 on C2: id = 5280, s = Hi, Mom! +' +'An open Shared method. +'Shared method M2 on C2: s = Hello, World! +'Shared method M2 on C2: s = Hi, Mom! +' +'A Shared method closed over the first argument (String). +'Shared method M2 on C2: s = Hello, World! +' +' diff --git a/snippets/visualbasic/System/Delegate/CreateDelegate/source.vb b/snippets/visualbasic/System/Delegate/CreateDelegate/source.vb new file mode 100644 index 00000000000..9964550f1d3 --- /dev/null +++ b/snippets/visualbasic/System/Delegate/CreateDelegate/source.vb @@ -0,0 +1,63 @@ +' +Imports System.Reflection + +' Define two classes to use in the demonstration, a base class and +' a class that derives from it. +' +Public Class Base +End Class + +Public Class Derived + Inherits Base + + ' Define a Shared method to use in the demonstration. The method + ' takes an instance of Base and returns an instance of Derived. + ' For the purposes of the demonstration, it is not necessary for + ' the method to do anything useful. + ' + Public Shared Function MyMethod(ByVal arg As Base) As Derived + Dim dummy As Base = arg + Return New Derived() + End Function + +End Class + +' Define a delegate that takes an instance of Derived and returns an +' instance of Base. +' +Public Delegate Function Example(ByVal arg As Derived) As Base + +Module Test + + Sub Main() + + ' The binding flags needed to retrieve MyMethod. + Dim flags As BindingFlags = _ + BindingFlags.Public Or BindingFlags.Static + + ' Get a MethodInfo that represents MyMethod. + Dim minfo As MethodInfo = _ + GetType(Derived).GetMethod("MyMethod", flags) + + ' Demonstrate contravariance of parameter types and covariance + ' of return types by using the delegate Example to represent + ' MyMethod. The delegate binds to the method because the + ' parameter of the delegate is more restrictive than the + ' parameter of the method (that is, the delegate accepts an + ' instance of Derived, which can always be safely passed to + ' a parameter of type Base), and the return type of MyMethod + ' is more restrictive than the return type of Example (that + ' is, the method returns an instance of Derived, which can + ' always be safely cast to type Base). + ' + Dim ex As Example = CType( _ + [Delegate].CreateDelegate(GetType(Example), minfo), _ + Example _ + ) + + ' Execute MyMethod using the delegate Example. + ' + Dim b As Base = ex(New Derived()) + End Sub +End Module +' diff --git a/snippets/visualbasic/System/Delegate/CreateDelegate/source1.vb b/snippets/visualbasic/System/Delegate/CreateDelegate/source1.vb new file mode 100644 index 00000000000..a9600807d5f --- /dev/null +++ b/snippets/visualbasic/System/Delegate/CreateDelegate/source1.vb @@ -0,0 +1,164 @@ +' Showing all the things D(A) can bind to. +' +' +Imports System.Reflection +Imports System.Security.Permissions + +' Declare a delegate type. The object of this code example +' is to show all the methods this delegate can bind to. +' +Public Delegate Sub D(ByVal c As C) + +' Declare two sample classes, C and F. Class C has an ID +' property so instances can be identified. +' +Public Class C + + Private _id As Integer + + Public ReadOnly Property ID() As Integer + Get + Return _id + End Get + End Property + + Public Sub New(ByVal newId As Integer) + Me._id = newId + End Sub + + Public Sub M1(ByVal c As C) + Console.WriteLine("Instance method M1(c As C) on C: this.id = {0}, c.ID = {1}", _ + Me.id, c.ID) + End Sub + + Public Sub M2() + Console.WriteLine("Instance method M2() on C: this.id = {0}", Me.id) + End Sub + + Public Shared Sub M3(ByVal c As C) + Console.WriteLine("Shared method M3(c As C) on C: c.ID = {0}", c.ID) + End Sub + + Public Shared Sub M4(ByVal c1 As C, ByVal c2 As C) + Console.WriteLine("Shared method M4(c1 As C, c2 As C) on C: c1.ID = {0}, c2.ID = {1}", _ + c1.ID, c2.ID) + End Sub +End Class + + +Public Class F + + Public Sub M1(ByVal c As C) + Console.WriteLine("Instance method M1(c As C) on F: c.ID = {0}", c.ID) + End Sub + + Public Shared Sub M3(ByVal c As C) + Console.WriteLine("Shared method M3(c As C) on F: c.ID = {0}", c.ID) + End Sub + + Public Shared Sub M4(ByVal f As F, ByVal c As C) + Console.WriteLine("Shared method M4(f As F, c As C) on F: c.ID = {0}", c.ID) + End Sub +End Class + +Public Class Example5 + + Public Shared Sub Main() + + Dim c1 As New C(42) + Dim c2 As New C(1491) + Dim f1 As New F() + + Dim d As D + + ' Instance method with one argument of type C. + Dim cmi1 As MethodInfo = GetType(C).GetMethod("M1") + ' Instance method with no arguments. + Dim cmi2 As MethodInfo = GetType(C).GetMethod("M2") + ' Shared method with one argument of type C. + Dim cmi3 As MethodInfo = GetType(C).GetMethod("M3") + ' Shared method with two arguments of type C. + Dim cmi4 As MethodInfo = GetType(C).GetMethod("M4") + + ' Instance method with one argument of type C. + Dim fmi1 As MethodInfo = GetType(F).GetMethod("M1") + ' Shared method with one argument of type C. + Dim fmi3 As MethodInfo = GetType(F).GetMethod("M3") + ' Shared method with an argument of type F and an + ' argument of type C. + Dim fmi4 As MethodInfo = GetType(F).GetMethod("M4") + + Console.WriteLine(vbLf & "An instance method on any type, with an argument of type C.") + ' D can represent any instance method that exactly matches its + ' signature. Methods on C and F are shown here. + ' + d = CType([Delegate].CreateDelegate(GetType(D), c1, cmi1), D) + d(c2) + d = CType([Delegate].CreateDelegate(GetType(D), f1, fmi1), D) + d(c2) + + Console.WriteLine(vbLf & "An instance method on C with no arguments.") + ' D can represent an instance method on C that has no arguments; + ' in this case, the argument of D represents the hidden first + ' argument of any instance method. The delegate acts like a + ' Shared method, and an instance of C must be passed each time + ' it is invoked. + ' + d = CType([Delegate].CreateDelegate(GetType(D), Nothing, cmi2), D) + d(c1) + + Console.WriteLine(vbLf & "A Shared method on any type, with an argument of type C.") + ' D can represent any Shared method with the same signature. + ' Methods on F and C are shown here. + ' + d = CType([Delegate].CreateDelegate(GetType(D), Nothing, cmi3), D) + d(c1) + d = CType([Delegate].CreateDelegate(GetType(D), Nothing, fmi3), D) + d(c1) + + Console.WriteLine(vbLf & "A Shared method on any type, with an argument of") + Console.WriteLine(" that type and an argument of type C.") + ' D can represent any Shared method with one argument of the + ' type the method belongs and a second argument of type C. + ' In this case, the method is closed over the instance of + ' supplied for the its first argument, and acts like an instance + ' method. Methods on F and C are shown here. + ' + d = CType([Delegate].CreateDelegate(GetType(D), c1, cmi4), D) + d(c2) + Dim test As [Delegate] = + [Delegate].CreateDelegate(GetType(D), f1, fmi4, False) + + ' This final example specifies False for throwOnBindFailure + ' in the call to CreateDelegate, so the variable 'test' + ' contains Nothing if the method fails to bind (for + ' example, if fmi4 happened to represent a method of + ' some class other than F). + ' + If test IsNot Nothing Then + d = CType(test, D) + d(c2) + End If + + End Sub +End Class + +' This code example produces the following output: +' +'An instance method on any type, with an argument of type C. +'Instance method M1(c As C) on C: this.id = 42, c.ID = 1491 +'Instance method M1(c As C) on F: c.ID = 1491 +' +'An instance method on C with no arguments. +'Instance method M2() on C: this.id = 42 +' +'A Shared method on any type, with an argument of type C. +'Shared method M3(c As C) on C: c.ID = 42 +'Shared method M3(c As C) on F: c.ID = 42 +' +'A Shared method on any type, with an argument of +' that type and an argument of type C. +'Shared method M4(c1 As C, c2 As C) on C: c1.ID = 42, c2.ID = 1491 +'Shared method M4(f As F, c As C) on F: c.ID = 1491 +' +' diff --git a/snippets/visualbasic/System/Double/CompareTo/Project.vbproj b/snippets/visualbasic/System/Double/CompareTo/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Double/CompareTo/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Double/CompareTo/compareto2.vb b/snippets/visualbasic/System/Double/CompareTo/compareto2.vb new file mode 100644 index 00000000000..abffb304b54 --- /dev/null +++ b/snippets/visualbasic/System/Double/CompareTo/compareto2.vb @@ -0,0 +1,21 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example + Public Sub Main() + Dim value1 As Double = 6.185 + Dim value2 As Double = value1 * .1 / .1 + Console.WriteLine("Comparing {0} and {1}: {2}", + value1, value2, value1.CompareTo(value2)) + Console.WriteLine() + Console.WriteLine("Comparing {0:R} and {1:R}: {2}", + value1, value2, value1.CompareTo(value2)) + End Sub +End Module +' The example displays the following output: +' Comparing 6.185 and 6.185: -1 +' +' Comparing 6.185 and 6.1850000000000005: -1 +' + diff --git a/snippets/visualbasic/System/Double/CompareTo/compareto3.vb b/snippets/visualbasic/System/Double/CompareTo/compareto3.vb new file mode 100644 index 00000000000..73823f71ad8 --- /dev/null +++ b/snippets/visualbasic/System/Double/CompareTo/compareto3.vb @@ -0,0 +1,21 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example2 + Public Sub Main() + Dim value1 As Double = 6.185 + Dim value2 As Object = value1 * .1 / .1 + Console.WriteLine("Comparing {0} and {1}: {2}", + value1, value2, value1.CompareTo(value2)) + Console.WriteLine() + Console.WriteLine("Comparing {0:R} and {1:R}: {2}", + value1, value2, value1.CompareTo(value2)) + End Sub +End Module +' The example displays the following output: +' Comparing 6.185 and 6.185: -1 +' +' Comparing 6.185 and 6.1850000000000005: -1 +' + diff --git a/snippets/visualbasic/System/Double/Epsilon/Equals_25051.vb b/snippets/visualbasic/System/Double/Epsilon/Equals_25051.vb new file mode 100644 index 00000000000..c0bd944424f --- /dev/null +++ b/snippets/visualbasic/System/Double/Epsilon/Equals_25051.vb @@ -0,0 +1,73 @@ +' Visual Basic .NET Document +Option Strict On + +Module modMain + + Public Sub Main() + CompareUsingEquals() + Console.WRiteLine() + CompareApproximateValues() + Console.WriteLIne() + CompareObjectsUsingEquals() + Console.WRiteLine() + CompareApproximateObjectValues() + Console.WriteLIne() + End Sub + + Private Sub CompareUsingEquals() + ' + ' Initialize two doubles with apparently identical values + Dim double1 As Double = .33333 + Dim double2 As Double = 1/3 + ' Compare them for equality + Console.WriteLine(double1.Equals(double2)) ' displays False + ' + End Sub + + Private Sub CompareApproximateValues() + ' + ' Initialize two doubles with apparently identical values + Dim double1 As Double = .33333 + Dim double2 As Double = 1/3 + ' Define the tolerance for variation in their values + Dim difference As Double = Math.Abs(double1 * .00001) + + ' Compare the values + ' The output to the console indicates that the two values are equal + If Math.Abs(double1 - double2) <= difference Then + Console.WriteLine("double1 and double2 are equal.") + Else + Console.WriteLine("double1 and double2 are unequal.") + End If + ' + End Sub + + Private Sub CompareObjectsUsingEquals() + ' + ' Initialize two doubles with apparently identical values + Dim double1 As Double = .33333 + Dim double2 As Object = 1/3 + ' Compare them for equality + Console.WriteLine(double1.Equals(double2)) ' displays False + ' + End Sub + + Private Sub CompareApproximateObjectValues() + ' + ' Initialize two doubles with apparently identical values + Dim double1 As Double = .33333 + Dim double2 As Object = 1/3 + ' Define the tolerance for variation in their values + Dim difference As Double = Math.Abs(double1 * .0001) + + ' Compare the values + ' The output to the console indicates that the two values are equal + If Math.Abs(double1 - CDbl(double2)) <= difference Then + Console.WriteLine("double1 and double2 are equal.") + Else + Console.WriteLine("double1 and double2 are unequal.") + End If + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Double/Epsilon/Project.vbproj b/snippets/visualbasic/System/Double/Epsilon/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Double/Epsilon/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Double/Epsilon/epsilon.vb b/snippets/visualbasic/System/Double/Epsilon/epsilon.vb new file mode 100644 index 00000000000..2d849282e55 --- /dev/null +++ b/snippets/visualbasic/System/Double/Epsilon/epsilon.vb @@ -0,0 +1,24 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example + Public Sub Main() + Dim values() As Double = { 0, Double.Epsilon, Double.Epsilon * .5 } + + For ctr As Integer = 0 To values.Length - 2 + For ctr2 As Integer = ctr + 1 To values.Length - 1 + Console.WriteLine("{0:r} = {1:r}: {2}", _ + values(ctr), values(ctr2), _ + values(ctr).Equals(values(ctr2))) + Next + Console.WriteLine() + Next + End Sub +End Module +' The example displays the following output: +' 0 = 4.94065645841247E-324: False +' 0 = 0: True +' +' 4.94065645841247E-324 = 0: False +' diff --git a/snippets/visualbasic/System/Double/Epsilon/epsilon1.vb b/snippets/visualbasic/System/Double/Epsilon/epsilon1.vb new file mode 100644 index 00000000000..93bdd094343 --- /dev/null +++ b/snippets/visualbasic/System/Double/Epsilon/epsilon1.vb @@ -0,0 +1,57 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example1 + Public Sub Main() + Dim values() As Double = { 0.0, Double.Epsilon } + For Each value In values + Console.WriteLine(GetComponentParts(value)) + Console.WriteLine() + Next + End Sub + + Private Function GetComponentParts(value As Double) As String + Dim result As String = String.Format("{0:R}: ", value) + Dim indent As Integer = result.Length + + ' Convert the double to an 8-byte array. + Dim bytes() As Byte = BitConverter.GetBytes(value) + ' Get the sign bit (byte 7, bit 7). + result += String.Format("Sign: {0}{1}", + If((bytes(7) And &H80) = &H80, "1 (-)", "0 (+)"), + vbCrLf) + + ' Get the exponent (byte 6 bits 4-7 to byte 7, bits 0-6) + Dim exponent As Integer = (bytes(7) And &H07F) << 4 + exponent = exponent Or ((bytes(6) And &HF0) >> 4) + Dim adjustment As Integer = If(exponent <> 0, 1023, 1022) + result += String.Format("{0}Exponent: 0x{1:X4} ({1}){2}", + New String(" "c, indent), exponent - adjustment, + vbCrLf) + + ' Get the significand (bits 0-51) + Dim significand As Long = ((bytes(6) And &H0F) << 48) + significand = significand Or (bytes(5) << 40) + significand = significand Or (bytes(4) << 32) + significand = significand Or (bytes(3) << 24) + significand = significand Or (bytes(2) << 16) + significand = significand Or (bytes(1) << 8) + significand = significand Or bytes(0) + result += String.Format("{0}Mantissa: 0x{1:X13}{2}", + New String(" "c, indent), significand, vbCrLf) + + Return result + End Function +End Module +' The example displays the following output: +' 0: Sign: 0 (+) +' Exponent: 0xFFFFFC02 (-1022) +' Mantissa: 0x0000000000000 +' +' +' 4.94065645841247E-324: Sign: 0 (+) +' Exponent: 0xFFFFFC02 (-1022) +' Mantissa: 0x0000000000001 +' + diff --git a/snippets/visualbasic/System/Double/Equals/Project.vbproj b/snippets/visualbasic/System/Double/Equals/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Double/Equals/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Double/Equals/equalsabs1.vb b/snippets/visualbasic/System/Double/Equals/equalsabs1.vb new file mode 100644 index 00000000000..8dcaf200668 --- /dev/null +++ b/snippets/visualbasic/System/Double/Equals/equalsabs1.vb @@ -0,0 +1,41 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example1 + Public Sub Main() + Dim value1 As Double = .1 * 10 + Dim value2 As Double = 0 + For ctr As Integer = 0 To 9 + value2 += .1 + Next + + Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, + HasMinimalDifference(value1, value2, 1)) + End Sub + + Public Function HasMinimalDifference(value1 As Double, value2 As Double, units As Integer) As Boolean + Dim lValue1 As long = BitConverter.DoubleToInt64Bits(value1) + Dim lValue2 As long = BitConverter.DoubleToInt64Bits(value2) + + ' If the signs are different, Return False except for +0 and -0. + If ((lValue1 >> 63) <> (lValue2 >> 63)) Then + If value1 = value2 Then + Return True + End If + Return False + End If + + Dim diff As Long = Math.Abs(lValue1 - lValue2) + + If diff <= units Then + Return True + End If + + Return False + End Function +End Module +' The example displays the following output: +' 1 = 0.99999999999999989: True +' + diff --git a/snippets/visualbasic/System/Double/Equals/equalsoverl.vb b/snippets/visualbasic/System/Double/Equals/equalsoverl.vb index 182238d9ef9..88fa88530d2 100644 --- a/snippets/visualbasic/System/Double/Equals/equalsoverl.vb +++ b/snippets/visualbasic/System/Double/Equals/equalsoverl.vb @@ -2,14 +2,14 @@ Option Strict On ' -Module Example +Module Example2 Dim value As Double = 112 - + Public Sub Main() Dim byte1 As Byte = 112 Console.WriteLine("value = byte1: {0,16}", value.Equals(byte1)) TestObjectForEquality(byte1) - + Dim short1 As Short = 112 Console.WriteLine("value = short1: {0,16}", value.Equals(short1)) TestObjectForEquality(short1) @@ -25,7 +25,7 @@ Module Example Dim sbyte1 As SByte = 112 Console.WriteLine("value = sbyte1: {0,16}", value.Equals(sbyte1)) TestObjectForEquality(sbyte1) - + Dim ushort1 As UShort = 112 Console.WriteLine("value = ushort1: {0,16}", value.Equals(ushort1)) TestObjectForEquality(ushort1) @@ -37,7 +37,7 @@ Module Example Dim ulong1 As ULong = 112 Console.WriteLine("value = ulong1: {0,17}", value.Equals(ulong1)) TestObjectForEquality(ulong1) - + Dim dec1 As Decimal = 112d Console.WriteLine("value = dec1: {0,20}", value.Equals(dec1)) TestObjectForEquality(dec1) @@ -46,7 +46,7 @@ Module Example Console.WriteLine("value = sng1: {0,19}", value.Equals(sng1)) TestObjectForEquality(sng1) End Sub - + Private Sub TestObjectForEquality(obj As Object) Console.WriteLine("{0} ({1}) = {2} ({3}): {4}", value, value.GetType().Name, diff --git a/snippets/visualbasic/System/Double/Overview/Program.vb b/snippets/visualbasic/System/Double/Overview/Program.vb new file mode 100644 index 00000000000..e02497b586f --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/Program.vb @@ -0,0 +1,6 @@ +Public Class Program + Public Shared Sub Main() + Example9.Run() + End Sub + +End Class diff --git a/snippets/visualbasic/System/Double/Overview/Project.vbproj b/snippets/visualbasic/System/Double/Overview/Project.vbproj index 874c98f3477..f99395b4b2b 100644 --- a/snippets/visualbasic/System/Double/Overview/Project.vbproj +++ b/snippets/visualbasic/System/Double/Overview/Project.vbproj @@ -1,7 +1,7 @@ - Library + Exe net10.0 diff --git a/snippets/visualbasic/System/Double/Overview/comparison1.vb b/snippets/visualbasic/System/Double/Overview/comparison1.vb new file mode 100644 index 00000000000..cd8375c243a --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/comparison1.vb @@ -0,0 +1,16 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example1 + Public Sub Run() + Dim value1 As Double = 0.333333333333333 + Dim value2 As Double = 1 / 3 + Console.WriteLine("{0} = {1}: {2}", value1, value2, value1.Equals(value2)) + End Sub +End Module + +' The example displays the following output: +' 0.333333333333333 = 0.33333333333333331: False +' + diff --git a/snippets/visualbasic/System/Double/Overview/comparison3.vb b/snippets/visualbasic/System/Double/Overview/comparison3.vb new file mode 100644 index 00000000000..571fb4fe0e9 --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/comparison3.vb @@ -0,0 +1,19 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example3 + Public Sub Run() + Dim value1 As Double = 0.333333333333333 + Dim value2 As Double = 1 / 3 + Dim precision As Integer = 7 + value1 = Math.Round(value1, precision) + value2 = Math.Round(value2, precision) + Console.WriteLine("{0} = {1}: {2}", value1, value2, value1.Equals(value2)) + End Sub +End Module + +' The example displays the following output: +' 0.3333333 = 0.3333333: True +' + diff --git a/snippets/visualbasic/System/Double/Overview/comparison4.vb b/snippets/visualbasic/System/Double/Overview/comparison4.vb new file mode 100644 index 00000000000..e778f956f8c --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/comparison4.vb @@ -0,0 +1,43 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example4 + Public Sub Run() + Dim one1 As Double = 0.1 * 10 + Dim one2 As Double = 0 + For ctr As Integer = 1 To 10 + one2 += 0.1 + Next + Console.WriteLine("{0} = {1}: {2}", one1, one2, one1.Equals(one2)) + Console.WriteLine("{0} is approximately equal to {1}: {2}", + one1, one2, + IsApproximatelyEqual(one1, one2, 0.000000001)) + End Sub + + Function IsApproximatelyEqual(value1 As Double, value2 As Double, + epsilon As Double) As Boolean + ' If they are equal anyway, just return True. + If value1.Equals(value2) Then Return True + + ' Handle NaN, Infinity. + If Double.IsInfinity(value1) Or Double.IsNaN(value1) Then + Return value1.Equals(value2) + ElseIf Double.IsInfinity(value2) Or Double.IsNaN(value2) Then + Return value1.Equals(value2) + End If + + ' Handle zero to avoid division by zero + Dim divisor As Double = Math.Max(value1, value2) + If divisor.Equals(0) Then + divisor = Math.Min(value1, value2) + End If + + Return Math.Abs((value1 - value2) / divisor) <= epsilon + End Function +End Module + +' The example displays the following output: +' 1 = 0.99999999999999989: False +' 1 is approximately equal to 0.99999999999999989: True +' diff --git a/snippets/visualbasic/System/Double/Overview/convert1.vb b/snippets/visualbasic/System/Double/Overview/convert1.vb new file mode 100644 index 00000000000..8d401a35a54 --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/convert1.vb @@ -0,0 +1,45 @@ +' Visual Basic .NET Document +'Option Strict On + +' +Module Example5 + Public Sub Run() + Dim values() As Object = {Byte.MinValue, Byte.MaxValue, Decimal.MinValue, + Decimal.MaxValue, Int16.MinValue, Int16.MaxValue, + Int32.MinValue, Int32.MaxValue, Int64.MinValue, + Int64.MaxValue, SByte.MinValue, SByte.MaxValue, + Single.MinValue, Single.MaxValue, UInt16.MinValue, + UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue, + UInt64.MinValue, UInt64.MaxValue} + Dim dblValue As Double + For Each value In values + dblValue = value + Console.WriteLine("{0} ({1}) --> {2:R} ({3})", + value, value.GetType().Name, + dblValue, dblValue.GetType().Name) + Next + End Sub +End Module +' The example displays the following output: +' 0 (Byte) --> 0 (Double) +' 255 (Byte) --> 255 (Double) +' -79228162514264337593543950335 (Decimal) --> -7.9228162514264338E+28 (Double) +' 79228162514264337593543950335 (Decimal) --> 7.9228162514264338E+28 (Double) +' -32768 (Int16) --> -32768 (Double) +' 32767 (Int16) --> 32767 (Double) +' -2147483648 (Int32) --> -2147483648 (Double) +' 2147483647 (Int32) --> 2147483647 (Double) +' -9223372036854775808 (Int64) --> -9.2233720368547758E+18 (Double) +' 9223372036854775807 (Int64) --> 9.2233720368547758E+18 (Double) +' -128 (SByte) --> -128 (Double) +' 127 (SByte) --> 127 (Double) +' -3.402823E+38 (Single) --> -3.4028234663852886E+38 (Double) +' 3.402823E+38 (Single) --> 3.4028234663852886E+38 (Double) +' 0 (UInt16) --> 0 (Double) +' 65535 (UInt16) --> 65535 (Double) +' 0 (UInt32) --> 0 (Double) +' 4294967295 (UInt32) --> 4294967295 (Double) +' 0 (UInt64) --> 0 (Double) +' 18446744073709551615 (UInt64) --> 1.8446744073709552E+19 (Double) +' + diff --git a/snippets/visualbasic/System/Double/Overview/convert2.vb b/snippets/visualbasic/System/Double/Overview/convert2.vb new file mode 100644 index 00000000000..b9fb4869ebb --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/convert2.vb @@ -0,0 +1,140 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example6 + Public Sub Run() + Dim values() As Double = {Double.MinValue, -67890.1234, -12345.6789, + 12345.6789, 67890.1234, Double.MaxValue, + Double.NaN, Double.PositiveInfinity, + Double.NegativeInfinity} + For Each value In values + Try + Dim lValue As Int64 = CLng(value) + Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})", + value, value.GetType().Name, + lValue, lValue.GetType().Name) + Catch e As OverflowException + Console.WriteLine("Unable to convert {0} to Int64.", value) + End Try + Try + Dim ulValue As UInt64 = CULng(value) + Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})", + value, value.GetType().Name, + ulValue, ulValue.GetType().Name) + Catch e As OverflowException + Console.WriteLine("Unable to convert {0} to UInt64.", value) + End Try + Try + Dim dValue As Decimal = CDec(value) + Console.WriteLine("{0} ({1}) --> {2} ({3})", + value, value.GetType().Name, + dValue, dValue.GetType().Name) + Catch e As OverflowException + Console.WriteLine("Unable to convert {0} to Decimal.", value) + End Try + Try + Dim sValue As Single = CSng(value) + Console.WriteLine("{0} ({1}) --> {2} ({3})", + value, value.GetType().Name, + sValue, sValue.GetType().Name) + Catch e As OverflowException + Console.WriteLine("Unable to convert {0} to Single.", value) + End Try + Console.WriteLine() + Next + End Sub +End Module +' The example displays the following output for conversions performed +' in a checked context: +' Unable to convert -1.79769313486232E+308 to Int64. +' Unable to convert -1.79769313486232E+308 to UInt64. +' Unable to convert -1.79769313486232E+308 to Decimal. +' -1.79769313486232E+308 (Double) --> -Infinity (Single) +' +' -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64) +' Unable to convert -67890.1234 to UInt64. +' -67890.1234 (Double) --> -67890.1234 (Decimal) +' -67890.1234 (Double) --> -67890.13 (Single) +' +' -12345.6789 (Double) --> -12346 (0xFFFFFFFFFFFFCFC6) (Int64) +' Unable to convert -12345.6789 to UInt64. +' -12345.6789 (Double) --> -12345.6789 (Decimal) +' -12345.6789 (Double) --> -12345.68 (Single) +' +' 12345.6789 (Double) --> 12346 (0x000000000000303A) (Int64) +' 12345.6789 (Double) --> 12346 (0x000000000000303A) (UInt64) +' 12345.6789 (Double) --> 12345.6789 (Decimal) +' 12345.6789 (Double) --> 12345.68 (Single) +' +' 67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64) +' 67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64) +' 67890.1234 (Double) --> 67890.1234 (Decimal) +' 67890.1234 (Double) --> 67890.13 (Single) +' +' Unable to convert 1.79769313486232E+308 to Int64. +' Unable to convert 1.79769313486232E+308 to UInt64. +' Unable to convert 1.79769313486232E+308 to Decimal. +' 1.79769313486232E+308 (Double) --> Infinity (Single) +' +' Unable to convert NaN to Int64. +' Unable to convert NaN to UInt64. +' Unable to convert NaN to Decimal. +' NaN (Double) --> NaN (Single) +' +' Unable to convert Infinity to Int64. +' Unable to convert Infinity to UInt64. +' Unable to convert Infinity to Decimal. +' Infinity (Double) --> Infinity (Single) +' +' Unable to convert -Infinity to Int64. +' Unable to convert -Infinity to UInt64. +' Unable to convert -Infinity to Decimal. +' -Infinity (Double) --> -Infinity (Single) +' The example displays the following output for conversions performed +' in an unchecked context: +' -1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +' -1.79769313486232E+308 (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64) +' Unable to convert -1.79769313486232E+308 to Decimal. +' -1.79769313486232E+308 (Double) --> -Infinity (Single) +' +' -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64) +' -67890.1234 (Double) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64) +' -67890.1234 (Double) --> -67890.1234 (Decimal) +' -67890.1234 (Double) --> -67890.13 (Single) +' +' -12345.6789 (Double) --> -12346 (0xFFFFFFFFFFFFCFC6) (Int64) +' -12345.6789 (Double) --> 18446744073709539270 (0xFFFFFFFFFFFFCFC6) (UInt64) +' -12345.6789 (Double) --> -12345.6789 (Decimal) +' -12345.6789 (Double) --> -12345.68 (Single) +' +' 12345.6789 (Double) --> 12346 (0x000000000000303A) (Int64) +' 12345.6789 (Double) --> 12346 (0x000000000000303A) (UInt64) +' 12345.6789 (Double) --> 12345.6789 (Decimal) +' 12345.6789 (Double) --> 12345.68 (Single) +' +' 67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64) +' 67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64) +' 67890.1234 (Double) --> 67890.1234 (Decimal) +' 67890.1234 (Double) --> 67890.13 (Single) +' +' 1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +' 1.79769313486232E+308 (Double) --> 0 (0x0000000000000000) (UInt64) +' Unable to convert 1.79769313486232E+308 to Decimal. +' 1.79769313486232E+308 (Double) --> Infinity (Single) +' +' NaN (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +' NaN (Double) --> 0 (0x0000000000000000) (UInt64) +' Unable to convert NaN to Decimal. +' NaN (Double) --> NaN (Single) +' +' Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +' Infinity (Double) --> 0 (0x0000000000000000) (UInt64) +' Unable to convert Infinity to Decimal. +' Infinity (Double) --> Infinity (Single) +' +' -Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64) +' -Infinity (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64) +' Unable to convert -Infinity to Decimal. +' -Infinity (Double) --> -Infinity (Single) +' diff --git a/snippets/visualbasic/System/Double/Overview/exceptional1.vb b/snippets/visualbasic/System/Double/Overview/exceptional1.vb new file mode 100644 index 00000000000..77f89f33d97 --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/exceptional1.vb @@ -0,0 +1,17 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example7 + Public Sub Run() + Dim value1 As Double = 1.1632875981534209E-225 + Dim value2 As Double = 9.1642346778E-175 + Dim result As Double = value1 * value2 + Console.WriteLine("{0} * {1} = {2}", value1, value2, result) + Console.WriteLine("{0} = 0: {1}", result, result.Equals(0.0)) + End Sub +End Module +' The example displays the following output: +' 1.16328759815342E-225 * 9.1642346778E-175 = 0 +' 0 = 0: True +' diff --git a/snippets/visualbasic/System/Double/Overview/exceptional2.vb b/snippets/visualbasic/System/Double/Overview/exceptional2.vb new file mode 100644 index 00000000000..e9bd92e8e5a --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/exceptional2.vb @@ -0,0 +1,29 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example8 + Public Sub Run() + Dim value1 As Double = 4.565E+153 + Dim value2 As Double = 6.9375E+172 + Dim result As Double = value1 * value2 + Console.WriteLine("PositiveInfinity: {0}", + Double.IsPositiveInfinity(result)) + Console.WriteLine("NegativeInfinity: {0}", + Double.IsNegativeInfinity(result)) + Console.WriteLine() + value1 = -value1 + result = value1 * value2 + Console.WriteLine("PositiveInfinity: {0}", + Double.IsPositiveInfinity(result)) + Console.WriteLine("NegativeInfinity: {0}", + Double.IsNegativeInfinity(result)) + End Sub +End Module +' The example displays the following output: +' PositiveInfinity: True +' NegativeInfinity: False +' +' PositiveInfinity: False +' NegativeInfinity: True +' diff --git a/snippets/visualbasic/System/Double/Overview/precision1.vb b/snippets/visualbasic/System/Double/Overview/precision1.vb new file mode 100644 index 00000000000..e5c96a27e8e --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/precision1.vb @@ -0,0 +1,24 @@ +' Visual Basic .NET Document +Option Strict On + +Module Example9 + Public Sub Run() + ' + Dim value As Double = -4.4233060424477198E-305 + + Dim fromLiteral As Double = -4.4233060424477198E-305 + Dim fromVariable As Double = value + Dim fromParse As Double = Double.Parse("-4.42330604244772E-305") + + Console.WriteLine("Double value from literal: {0,29:R}", fromLiteral) + Console.WriteLine("Double value from variable: {0,28:R}", fromVariable) + Console.WriteLine("Double value from Parse method: {0,24:R}", fromParse) + + ' The output is: + ' Double value from literal: -4.42330604244772E-305 + ' Double value from variable: -4.42330604244772E-305 + ' Double value from Parse method: -4.42330604244772E-305 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Double/Overview/precisionlist1.vb b/snippets/visualbasic/System/Double/Overview/precisionlist1.vb index efbde3e8e96..2eee989f595 100644 --- a/snippets/visualbasic/System/Double/Overview/precisionlist1.vb +++ b/snippets/visualbasic/System/Double/Overview/precisionlist1.vb @@ -3,7 +3,7 @@ Option Strict On ' Module Example10 - Public Sub Main() + Public Sub Run() Dim value1 As Double = 1 / 3 Dim sValue2 As Single = 1 / 3 Dim value2 As Double = CDbl(sValue2) diff --git a/snippets/visualbasic/System/Double/Overview/precisionlist3.vb b/snippets/visualbasic/System/Double/Overview/precisionlist3.vb new file mode 100644 index 00000000000..877b6914a8f --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/precisionlist3.vb @@ -0,0 +1,27 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example11 + Public Sub Run() + Dim values() As Double = {10.0, 2.88, 2.88, 2.88, 9.0} + Dim result As Double = 27.64 + Dim total As Double + For Each value In values + total += value + Next + If total.Equals(result) Then + Console.WriteLine("The sum of the values equals the total.") + Else + Console.WriteLine("The sum of the values ({0}) does not equal the total ({1}).", + total, result) + End If + End Sub +End Module +' The example displays the following output: +' The sum of the values (36.64) does not equal the total (36.64). +' +' If the index items in the Console.WriteLine statement are changed to {0:R}, +' the example displays the following output: +' The sum of the values (27.639999999999997) does not equal the total (27.64). +' diff --git a/snippets/visualbasic/System/Double/Overview/precisionlist4.vb b/snippets/visualbasic/System/Double/Overview/precisionlist4.vb new file mode 100644 index 00000000000..983d7ac9ee1 --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/precisionlist4.vb @@ -0,0 +1,36 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO + +Module Example12 + Public Sub Run() + Dim sw As New StreamWriter(".\Doubles.dat") + Dim values() As Double = {2.2 / 1.01, 1.0 / 3, Math.PI} + For ctr As Integer = 0 To values.Length - 1 + sw.Write(values(ctr).ToString()) + If ctr <> values.Length - 1 Then sw.Write("|") + Next + sw.Close() + + Dim restoredValues(values.Length - 1) As Double + Dim sr As New StreamReader(".\Doubles.dat") + Dim temp As String = sr.ReadToEnd() + Dim tempStrings() As String = temp.Split("|"c) + For ctr As Integer = 0 To tempStrings.Length - 1 + restoredValues(ctr) = Double.Parse(tempStrings(ctr)) + Next + + For ctr As Integer = 0 To values.Length - 1 + Console.WriteLine("{0} {2} {1}", values(ctr), + restoredValues(ctr), + If(values(ctr).Equals(restoredValues(ctr)), "=", "<>")) + Next + End Sub +End Module +' The example displays the following output: +' 2.17821782178218 <> 2.17821782178218 +' 0.333333333333333 <> 0.333333333333333 +' 3.14159265358979 <> 3.14159265358979 +' diff --git a/snippets/visualbasic/System/Double/Overview/representation1.vb b/snippets/visualbasic/System/Double/Overview/representation1.vb new file mode 100644 index 00000000000..50197a8a402 --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/representation1.vb @@ -0,0 +1,21 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example14 + Public Sub Run() + Dim value As Double = 0.1 + Dim result1 As Double = value * 10 + Dim result2 As Double + For ctr As Integer = 1 To 10 + result2 += value + Next + Console.WriteLine(".1 * 10: {0:R}", result1) + Console.WriteLine(".1 Added 10 times: {0:R}", result2) + End Sub +End Module +' The example displays the following output: +' .1 * 10: 1 +' .1 Added 10 times: 0.99999999999999989 +' + diff --git a/snippets/visualbasic/System/Double/Overview/representation2.vb b/snippets/visualbasic/System/Double/Overview/representation2.vb new file mode 100644 index 00000000000..572a0dec9d2 --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/representation2.vb @@ -0,0 +1,16 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example15 + Public Sub Run() + Dim value As Double = 123456789012.34567 + Dim additional As Double = Double.Epsilon * 1.0E+15 + Console.WriteLine("{0} + {1} = {2}", value, additional, + value + additional) + End Sub +End Module +' The example displays the following output: +' 123456789012.346 + 4.94065645841247E-309 = 123456789012.346 +' + diff --git a/snippets/visualbasic/System/Double/Overview/source.vb b/snippets/visualbasic/System/Double/Overview/source.vb new file mode 100644 index 00000000000..5a4cfeb7bdd --- /dev/null +++ b/snippets/visualbasic/System/Double/Overview/source.vb @@ -0,0 +1,399 @@ +Imports System.Globalization + +Namespace Snippets + Class Launcher + Public Overloads Shared Sub Run() + Dim t1 As Temperature = Temperature.Parse("20'F", NumberStyles.Float, Nothing) + Console.WriteLine(t1.ToString("F", Nothing)) + + Dim str1 As String = t1.ToString("C", Nothing) + Console.WriteLine(str1) + + Dim t2 As Temperature = Temperature.Parse(str1, NumberStyles.Float, Nothing) + Console.WriteLine(t2.ToString("F", Nothing)) + + Console.WriteLine(t1.CompareTo(t2)) + + Dim t3 As Temperature = Temperature.Parse("20'C", NumberStyles.Float, Nothing) + Console.WriteLine(t3.ToString("F", Nothing)) + + Console.WriteLine(t1.CompareTo(t3)) + + Console.ReadLine() + End Sub + End Class + ' + ' Temperature class stores the value as Double + ' and delegates most of the functionality + ' to the Double implementation. + Public Class Temperature + Implements IComparable, IFormattable + + Public Overloads Function CompareTo(ByVal obj As Object) As Integer _ + Implements IComparable.CompareTo + + If TypeOf obj Is Temperature Then + Dim temp As Temperature = CType(obj, Temperature) + + Return m_value.CompareTo(temp.m_value) + End If + + Throw New ArgumentException("object is not a Temperature") + End Function + + Public Overloads Function ToString(ByVal format As String, ByVal provider As IFormatProvider) As String _ + Implements IFormattable.ToString + + If Not (format Is Nothing) Then + If format.Equals("F") Then + Return [String].Format("{0}'F", Me.Value.ToString()) + End If + If format.Equals("C") Then + Return [String].Format("{0}'C", Me.Celsius.ToString()) + End If + End If + + Return m_value.ToString(format, provider) + End Function + + ' Parses the temperature from a string in form + ' [ws][sign]digits['F|'C][ws] + Public Shared Function Parse(ByVal s As String, ByVal styles As NumberStyles, ByVal provider As IFormatProvider) As Temperature + Dim temp As New Temperature() + + If s.TrimEnd().EndsWith("'F") Then + temp.Value = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles, provider) + Else + If s.TrimEnd().EndsWith("'C") Then + temp.Celsius = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles, provider) + Else + temp.Value = Double.Parse(s, styles, provider) + End If + End If + Return temp + End Function + + ' The value holder + Protected m_value As Double + + Public Property Value() As Double + Get + Return m_value + End Get + Set(ByVal Value As Double) + m_value = Value + End Set + End Property + + Public Property Celsius() As Double + Get + Return (m_value - 32) / 1.8 + End Get + Set(ByVal Value As Double) + m_value = Value * 1.8 + 32 + End Set + End Property + End Class + ' +End Namespace + +Namespace Snippets2 + ' + Public Class Temperature + + Public Shared ReadOnly Property MinValue() As Double + Get + Return Double.MinValue + End Get + End Property + + Public Shared ReadOnly Property MaxValue() As Double + Get + Return Double.MaxValue + End Get + End Property + + ' The value holder + Protected m_value As Double + + Public Property Value() As Double + Get + Return m_value + End Get + Set(ByVal Value As Double) + m_value = Value + End Set + End Property + + Public Property Celsius() As Double + Get + Return (m_value - 32) / 1.8 + End Get + Set(ByVal Value As Double) + m_value = Value * 1.8 + 32 + End Set + End Property + End Class + ' +End Namespace + +Namespace Snippets3 + ' + Public Class Temperature + Implements IComparable + + Public Overloads Function CompareTo(ByVal obj As Object) As Integer _ + Implements IComparable.CompareTo + + If TypeOf obj Is Temperature Then + Dim temp As Temperature = CType(obj, Temperature) + + Return m_value.CompareTo(temp.m_value) + End If + + Throw New ArgumentException("object is not a Temperature") + End Function + + ' The value holder + Protected m_value As Double + + Public Property Value() As Double + Get + Return m_value + End Get + Set(ByVal Value As Double) + m_value = Value + End Set + End Property + + Public Property Celsius() As Double + Get + Return (m_value - 32) / 1.8 + End Get + Set(ByVal Value As Double) + m_value = Value * 1.8 + 32 + End Set + End Property + End Class + ' +End Namespace + +Namespace Snippets4 + ' + Public Class Temperature + Implements IFormattable + + Public Overloads Function ToString(ByVal format As String, ByVal provider As IFormatProvider) As String _ + Implements IFormattable.ToString + + If Not (format Is Nothing) Then + If format.Equals("F") Then + Return [String].Format("{0}'F", Me.Value.ToString()) + End If + If format.Equals("C") Then + Return [String].Format("{0}'C", Me.Celsius.ToString()) + End If + End If + + Return m_value.ToString(format, provider) + End Function + + ' The value holder + Protected m_value As Double + + Public Property Value() As Double + Get + Return m_value + End Get + Set(ByVal Value As Double) + m_value = Value + End Set + End Property + + Public Property Celsius() As Double + Get + Return (m_value - 32) / 1.8 + End Get + Set(ByVal Value As Double) + m_value = Value * 1.8 + 32 + End Set + End Property + End Class + ' +End Namespace + +Namespace Snippets5 + ' + Public Class Temperature + ' Parses the temperature from a string in form + ' [ws][sign]digits['F|'C][ws] + Public Shared Function Parse(ByVal s As String) As Temperature + Dim temp As New Temperature() + + If s.TrimEnd().EndsWith("'F") Then + temp.Value = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2)) + Else + If s.TrimEnd().EndsWith("'C") Then + temp.Celsius = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2)) + Else + temp.Value = Double.Parse(s) + End If + End If + Return temp + End Function 'Parse + + ' The value holder + Protected m_value As Double + + Public Property Value() As Double + Get + Return m_value + End Get + Set(ByVal Value As Double) + m_value = Value + End Set + End Property + + Public Property Celsius() As Double + Get + Return (m_value - 32) / 1.8 + End Get + Set(ByVal Value As Double) + m_value = Value * 1.8 + 32 + End Set + End Property + End Class + ' +End Namespace + +Namespace Snippets6 + ' + Public Class Temperature + ' Parses the temperature from a string in form + ' [ws][sign]digits['F|'C][ws] + Public Shared Function Parse(ByVal s As String, ByVal provider As IFormatProvider) As Temperature + Dim temp As New Temperature() + + If s.TrimEnd().EndsWith("'F") Then + temp.Value = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), provider) + Else + If s.TrimEnd().EndsWith("'C") Then + temp.Celsius = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), provider) + Else + temp.Value = Double.Parse(s, provider) + End If + End If + Return temp + End Function 'Parse + + ' The value holder + Protected m_value As Double + + Public Property Value() As Double + Get + Return m_value + End Get + Set(ByVal Value As Double) + m_value = Value + End Set + End Property + + Public Property Celsius() As Double + Get + Return (m_value - 32) / 1.8 + End Get + Set(ByVal Value As Double) + m_value = Value * 1.8 + 32 + End Set + End Property + End Class + ' +End Namespace + +Namespace Snippets7 + ' + Public Class Temperature + ' Parses the temperature from a string in form + ' [ws][sign]digits['F|'C][ws] + Public Shared Function Parse(ByVal s As String, ByVal styles As NumberStyles) As Temperature + Dim temp As New Temperature() + + If s.TrimEnd().EndsWith("'F") Then + temp.Value = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles) + Else + If s.TrimEnd().EndsWith("'C") Then + temp.Celsius = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles) + Else + temp.Value = Double.Parse(s, styles) + End If + End If + Return temp + End Function + + ' The value holder + Protected m_value As Double + + Public Property Value() As Double + Get + Return m_value + End Get + Set(ByVal Value As Double) + m_value = Value + End Set + End Property + + Public Property Celsius() As Double + Get + Return (m_value - 32) / 1.8 + End Get + Set(ByVal Value As Double) + m_value = Value * 1.8 + 32 + End Set + End Property + End Class + ' +End Namespace + +Namespace Snippets8 + ' + Public Class Temperature + ' Parses the temperature from a string in form + ' [ws][sign]digits['F|'C][ws] + Public Shared Function Parse(ByVal s As String, ByVal styles As NumberStyles, ByVal provider As IFormatProvider) As Temperature + Dim temp As New Temperature() + + If s.TrimEnd().EndsWith("'F") Then + temp.Value = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles, provider) + Else + If s.TrimEnd().EndsWith("'C") Then + temp.Celsius = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles, provider) + Else + temp.Value = Double.Parse(s, styles, provider) + End If + End If + Return temp + End Function + + ' The value holder + Protected m_value As Double + + Public Property Value() As Double + Get + Return m_value + End Get + Set(ByVal Value As Double) + m_value = Value + End Set + End Property + + Public Property Celsius() As Double + Get + Return (m_value - 32) / 1.8 + End Get + Set(ByVal Value As Double) + m_value = Value * 1.8 + 32 + End Set + End Property + End Class + ' +End Namespace diff --git a/snippets/visualbasic/System/Enum/Overview/EnumMain.vb b/snippets/visualbasic/System/Enum/Overview/EnumMain.vb new file mode 100644 index 00000000000..c13d32be19f --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/EnumMain.vb @@ -0,0 +1,50 @@ +' +Public Class EnumTest + Enum Days + Saturday + Sunday + Monday + Tuesday + Wednesday + Thursday + Friday + End Enum + + Enum BoilingPoints + Celsius = 100 + Fahrenheit = 212 + End Enum + + _ + Enum Colors + Red = 1 + Green = 2 + Blue = 4 + Yellow = 8 + End Enum + + Public Shared Sub Main() + Dim weekdays As Type = GetType(Days) + Dim boiling As Type = GetType(BoilingPoints) + + Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:") + + Dim s As String + For Each s In [Enum].GetNames(weekdays) + Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(weekdays, [Enum].Parse(weekdays, s), "d")) + + Next s + Console.WriteLine() + Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.") + Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:") + + For Each s In [Enum].GetNames(boiling) + Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(boiling, [Enum].Parse(boiling, s), "d")) + Next s + + Dim myColors As Colors = Colors.Red Or Colors.Blue Or Colors.Yellow + Console.WriteLine() + Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors) + End Sub +End Class +' diff --git a/snippets/visualbasic/System/Enum/Overview/Extensions.vb b/snippets/visualbasic/System/Enum/Overview/Extensions.vb new file mode 100644 index 00000000000..127cd1ad24d --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/Extensions.vb @@ -0,0 +1,53 @@ +' +Imports System.Runtime.CompilerServices + +' Define an enumeration to represent student grades. +Public Enum Grades As Integer + F = 0 + D = 1 + C = 2 + B = 3 + A = 4 +End Enum + +' Define an extension method for the Grades enumeration. +Public Module Extensions + Public minPassing As Grades = Grades.D + + + Public Function Passing(grade As Grades) As Boolean + Return grade >= minPassing + End Function +End Module + +Public Module Example + Public Sub Main() + Dim g1 As Grades = Grades.D + Dim g2 As Grades = Grades.F + Console.WriteLine("{0} {1} a passing grade.", + g1, If(g1.Passing(), "is", "is not")) + Console.WriteLine("{0} {1} a passing grade.", + g2, If(g2.Passing(), "is", "is not")) + Console.WriteLine() + + Extensions.minPassing = Grades.C + Console.WriteLine("Raising the bar!") + Console.WriteLine() + Console.WriteLine("{0} {1} a passing grade.", + g1, If(g1.Passing(), "is", "is not")) + Console.WriteLine("{0} {1} a passing grade.", + g2, If(g2.Passing(), "is", "is not")) + End Sub +End Module + +' The example displays the following output: +' D is a passing grade. +' F is not a passing grade. +' +' Raising the bar! +' +' D is not a passing grade. +' F is not a passing grade. +' + + diff --git a/snippets/visualbasic/System/Enum/Overview/Project.vbproj b/snippets/visualbasic/System/Enum/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Enum/Overview/class1.vb b/snippets/visualbasic/System/Enum/Overview/class1.vb new file mode 100644 index 00000000000..7d20b0f1236 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/class1.vb @@ -0,0 +1,21 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Enum ArrivalStatus1 As Integer + Late = -1 + OnTime = 0 + Early = 1 +End Enum +' + +' +Public Module Example1 + Public Sub Main() + Dim status As ArrivalStatus1 = ArrivalStatus1.OnTime + Console.WriteLine("Arrival Status: {0} ({0:D})", status) + End Sub +End Module +' The example displays the following output: +' Arrival Status: OnTime (0) +' diff --git a/snippets/visualbasic/System/Enum/Overview/class2.vb b/snippets/visualbasic/System/Enum/Overview/class2.vb new file mode 100644 index 00000000000..502d2a09753 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/class2.vb @@ -0,0 +1,38 @@ +' Visual Basic .NET Document +Option Strict On + +Public Enum ArrivalStatus2 As Integer + Late = -1 + OnTime = 0 + Early = 1 +End Enum + +Public Module Example2 + Public Sub Main() + ' + Dim status1 As New ArrivalStatus2() + Console.WriteLine("Arrival Status: {0} ({0:D})", status1) + ' The example displays the following output: + ' Arrival Status: OnTime (0) + ' + + ' + Dim status2 As ArrivalStatus2 = CType(1, ArrivalStatus2) + Console.WriteLine("Arrival Status: {0} ({0:D})", status2) + ' The example displays the following output: + ' Arrival Status: Early (1) + ' + + ' + Dim value3 As Integer = 2 + Dim status3 As ArrivalStatus2 = CType(value3, ArrivalStatus2) + + Dim value4 As Integer = CInt(status3) + ' + + ' + Dim number As Integer = -1 + Dim arrived As ArrivalStatus2 = CType(ArrivalStatus2.ToObject(GetType(ArrivalStatus2), number), ArrivalStatus2) + ' + End Sub +End Module diff --git a/snippets/visualbasic/System/Enum/Overview/classbitwise1.vb b/snippets/visualbasic/System/Enum/Overview/classbitwise1.vb new file mode 100644 index 00000000000..be06a7128f5 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/classbitwise1.vb @@ -0,0 +1,65 @@ +' Visual Basic .NET Document +'Option Strict On + +' + Public Enum Pets As Integer + None = 0 + Dog = 1 + Cat = 2 + Bird = 4 + Rodent = 8 + Reptile = 16 + Other = 32 +End Enum +' + +Module Example3 + Public Sub Main() + ' + Dim familyPets As Pets = Pets.Dog Or Pets.Cat + Console.WriteLine("Pets: {0:G} ({0:D})", familyPets) + ' The example displays the following output: + ' Pets: Dog, Cat (3) + ' + + ShowHasFlag() + ShowIfSet() + TestForNone() + End Sub + + Private Sub ShowHasFlag() + ' + Dim familyPets As Pets = Pets.Dog Or Pets.Cat + If familyPets.HasFlag(Pets.Dog) Then + Console.WriteLine("The family has a dog.") + End If + ' The example displays the following output: + ' The family has a dog. + ' + End Sub + + Private Sub ShowIfSet() + ' + Dim familyPets As Pets = Pets.Dog Or Pets.Cat + If familyPets And Pets.Dog = Pets.Dog Then + Console.WriteLine("The family has a dog.") + End If + ' The example displays the following output: + ' The family has a dog. + ' + End Sub + + Private Sub TestForNone() + ' + Dim familyPets As Pets = Pets.Dog Or Pets.Cat + If familyPets = Pets.None Then + Console.WriteLine("The family has no pets.") + Else + Console.WriteLine("The family has pets.") + End If + ' The example displays the following output: + ' The family has pets. + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Enum/Overview/classconversion1.vb b/snippets/visualbasic/System/Enum/Overview/classconversion1.vb new file mode 100644 index 00000000000..92ddf702d35 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/classconversion1.vb @@ -0,0 +1,35 @@ +' Visual Basic .NET Document +Option Strict On +Option Infer On + +' +Public Enum ArrivalStatus4 As Integer + Unknown = -3 + Late = -1 + OnTime = 0 + Early = 1 +End Enum + +Module Example4 + Public Sub Main() + Dim values() As Integer = {-3, -1, 0, 1, 5, Int32.MaxValue} + For Each value In values + Dim status As ArrivalStatus4 + If [Enum].IsDefined(GetType(ArrivalStatus4), value) Then + status = CType(value, ArrivalStatus4) + Else + status = ArrivalStatus4.Unknown + End If + Console.WriteLine("Converted {0:N0} to {1}", value, status) + Next + End Sub +End Module +' The example displays the following output: +' Converted -3 to Unknown +' Converted -1 to Late +' Converted 0 to OnTime +' Converted 1 to Early +' Converted 5 to Unknown +' Converted 2,147,483,647 to Unknown +' + diff --git a/snippets/visualbasic/System/Enum/Overview/classconversion2.vb b/snippets/visualbasic/System/Enum/Overview/classconversion2.vb new file mode 100644 index 00000000000..a11e32e0e04 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/classconversion2.vb @@ -0,0 +1,23 @@ +' Visual Basic .NET Document +Option Strict On +Option Infer On + +Public Enum ArrivalStatus5 As Integer + Unknown = -3 + Late = -1 + OnTime = 0 + Early = 1 +End Enum + +Module Example5 + Public Sub Main() + ' + Dim status As ArrivalStatus5 = ArrivalStatus5.Early + Dim number = Convert.ChangeType(status, [Enum].GetUnderlyingType(GetType(ArrivalStatus5))) + Console.WriteLine("Converted {0} to {1}", status, number) + ' The example displays the following output: + ' Converted Early to 1 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Enum/Overview/classformat1.vb b/snippets/visualbasic/System/Enum/Overview/classformat1.vb new file mode 100644 index 00000000000..62716176bb6 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/classformat1.vb @@ -0,0 +1,27 @@ +' Visual Basic .NET Document +Option Strict On + +Public Enum ArrivalStatus6 As Integer + Unknown = -3 + Late = -1 + OnTime = 0 + Early = 1 +End Enum + +Module Example6 + Public Sub Main() + ' + Dim formats() As String = {"G", "F", "D", "X"} + Dim status As ArrivalStatus6 = ArrivalStatus6.Late + For Each fmt As String In formats + Console.WriteLine(status.ToString(fmt)) + Next + ' The example displays the following output: + ' Late + ' Late + ' -1 + ' FFFFFFFF + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Enum/Overview/classiterate.vb b/snippets/visualbasic/System/Enum/Overview/classiterate.vb new file mode 100644 index 00000000000..d4f5c5313d2 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/classiterate.vb @@ -0,0 +1,56 @@ +' Visual Basic .NET Document +Option Strict On +Option Infer On + +Public Enum ArrivalStatus7 As Integer + Unknown = -3 + Late = -1 + OnTime = 0 + Early = 1 +End Enum + +Module Example7 + Public Sub Main() + GetEnumByName() + Console.WriteLine("-----") + GetEnumByValue() + End Sub + + Private Sub GetEnumByName() + ' + Dim names() As String = [Enum].GetNames(GetType(ArrivalStatus7)) + Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name) + Array.Sort(names) + For Each name In names + Dim status As ArrivalStatus7 = CType([Enum].Parse(GetType(ArrivalStatus7), name), + ArrivalStatus7) + Console.WriteLine(" {0} ({0:D})", status) + Next + ' The example displays the following output: + ' Members of ArrivalStatus7: + ' Early (1) + ' Late (-1) + ' OnTime (0) + ' Unknown (-3) + ' + End Sub + + Private Sub GetEnumByValue() + ' + Dim values = [Enum].GetValues(GetType(ArrivalStatus7)) + Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name) + For Each value In values + Dim status As ArrivalStatus7 = CType([Enum].ToObject(GetType(ArrivalStatus7), value), + ArrivalStatus7) + Console.WriteLine(" {0} ({0:D})", status) + Next + ' The example displays the following output: + ' Members of ArrivalStatus7: + ' OnTime (0) + ' Early (1) + ' Unknown (-3) + ' Late (-1) + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Enum/Overview/classparse1.vb b/snippets/visualbasic/System/Enum/Overview/classparse1.vb new file mode 100644 index 00000000000..dfc231b8f40 --- /dev/null +++ b/snippets/visualbasic/System/Enum/Overview/classparse1.vb @@ -0,0 +1,42 @@ +' Visual Basic .NET Document +Option Strict On +Option Infer On + +Public Enum ArrivalStatus8 As Integer + Unknown = -3 + Late = -1 + OnTime = 0 + Early = 1 +End Enum + +Module Example8 + Public Sub Main() + ' + Dim number As String = "-1" + Dim name As String = "Early" + Dim invalid As String = "32" + + Try + Dim status1 As ArrivalStatus8 = CType([Enum].Parse(GetType(ArrivalStatus8), number), ArrivalStatus8) + If Not [Enum].IsDefined(GetType(ArrivalStatus8), status1) Then status1 = ArrivalStatus8.Unknown + Console.WriteLine("Converted '{0}' to {1}", number, status1) + Catch e As FormatException + Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.", + number) + End Try + + Dim status2 As ArrivalStatus8 + If [Enum].TryParse(Of ArrivalStatus8)(name, status2) Then + If Not [Enum].IsDefined(GetType(ArrivalStatus8), status2) Then status2 = ArrivalStatus8.Unknown + Console.WriteLine("Converted '{0}' to {1}", name, status2) + Else + Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.", + number) + End If + ' The example displays the following output: + ' Converted '-1' to Late + ' Converted 'Early' to Early + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Exception/Overview/Project.vbproj b/snippets/visualbasic/System/Exception/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Exception/Overview/catchexception.vb b/snippets/visualbasic/System/Exception/Overview/catchexception.vb new file mode 100644 index 00000000000..5c7c271bc3a --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/catchexception.vb @@ -0,0 +1,21 @@ +' +Class ExceptionTestClass + + Public Shared Sub Main() + Dim x As Integer = 0 + Try + Dim y As Integer = 100 / x + Catch e As ArithmeticException + Console.WriteLine("ArithmeticException Handler: {0}", e.ToString()) + Catch e As Exception + Console.WriteLine("Generic Exception Handler: {0}", e.ToString()) + End Try + End Sub +End Class +' +'This code example produces the following results: +' +'ArithmeticException Handler: System.OverflowException: Arithmetic operation resulted in an overflow. +' at ExceptionTestClass.Main() +' +' \ No newline at end of file diff --git a/snippets/visualbasic/System/Exception/Overview/example.vb b/snippets/visualbasic/System/Exception/Overview/example.vb new file mode 100644 index 00000000000..91ebfa1e56e --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/example.vb @@ -0,0 +1,48 @@ +Option Strict Off + +' +Imports System.Reflection + +Module Example + Sub Main() + Dim limit As Integer = 10000000 + Dim primes As New PrimeNumberGenerator(limit) + Dim start As Integer = 1000001 + Try + Dim values() As Integer = primes.GetPrimesFrom(start) + Console.WriteLine("There are {0} prime numbers from {1} to {2}", + start, limit) + Catch e As NotPrimeException + Console.WriteLine("{0} is not prime", e.NonPrime) + Console.WriteLine(e) + Console.WriteLine("--------") + End Try + + Dim domain As AppDomain = AppDomain.CreateDomain("Domain2") + Dim gen As PrimeNumberGenerator = domain.CreateInstanceAndUnwrap( + GetType(Example).Assembly.FullName, + "PrimeNumberGenerator", True, + BindingFlags.Default, Nothing, + {1000000}, Nothing, Nothing) + Try + start = 100 + Console.WriteLine(gen.GetPrimesFrom(start)) + Catch e As NotPrimeException + Console.WriteLine("{0} is not prime", e.NonPrime) + Console.WriteLine(e) + Console.WriteLine("--------") + End Try + End Sub +End Module +' The example displays the following output: +' 1000001 is not prime +' NotPrimeException: 1000001 is not a prime number. +' at PrimeNumberGenerator.GetPrimesFrom(Int32 prime) +' at Example.Main() +' -------- +' 100 is not prime +' NotPrimeException: 100 is not a prime number. +' at PrimeNumberGenerator.GetPrimesFrom(Int32 prime) +' at Example.Main() +' -------- +' diff --git a/snippets/visualbasic/System/Exception/Overview/notprimeexception.vb b/snippets/visualbasic/System/Exception/Overview/notprimeexception.vb new file mode 100644 index 00000000000..ee0d31fc208 --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/notprimeexception.vb @@ -0,0 +1,38 @@ +' +Imports System.Runtime.Serialization + + _ +Public Class NotPrimeException : Inherits Exception + Private notAPrime As Integer + + Protected Sub New() + MyBase.New() + End Sub + + Public Sub New(value As Integer) + MyBase.New(String.Format("{0} is not a prime number.", value)) + notAPrime = value + End Sub + + Public Sub New(value As Integer, message As String) + MyBase.New(message) + notAPrime = value + End Sub + + Public Sub New(value As Integer, message As String, innerException As Exception) + MyBase.New(message, innerException) + notAPrime = value + End Sub + + Protected Sub New(info As SerializationInfo, + context As StreamingContext) + MyBase.New(info, context) + End Sub + + Public ReadOnly Property NonPrime As Integer + Get + Return notAPrime + End Get + End Property +End Class +' diff --git a/snippets/visualbasic/System/Exception/Overview/primenumbergenerator.vb b/snippets/visualbasic/System/Exception/Overview/primenumbergenerator.vb new file mode 100644 index 00000000000..1d0f191d15b --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/primenumbergenerator.vb @@ -0,0 +1,62 @@ +' +Imports System.Collections.Generic + + Public Class PrimeNumberGenerator + Private Const START As Integer = 2 + Private maxUpperBound As Integer = 10000000 + Private upperBound As Integer + Private primeTable() As Boolean + Private primes As New List(Of Integer) + + Public Sub New(upperBound As Integer) + If upperBound > maxUpperBound Then + Dim message As String = String.Format( + "{0} exceeds the maximum upper bound of {1}.", + upperBound, maxUpperBound) + Throw New ArgumentOutOfRangeException(message) + End If + Me.upperBound = upperBound + ' Create array and mark 0, 1 as not prime (True). + ReDim primeTable(upperBound) + primeTable(0) = True + primeTable(1) = True + + ' Use Sieve of Eratosthenes to determine prime numbers. + For ctr As Integer = START To CInt(Math.Ceiling(Math.Sqrt(upperBound))) + If primeTable(ctr) Then Continue For + + For multiplier As Integer = ctr To CInt(upperBound \ ctr) + If ctr * multiplier <= upperBound Then primeTable(ctr * multiplier) = True + Next + Next + ' Populate array with prime number information. + Dim index As Integer = START + Do While index <> -1 + index = Array.FindIndex(primeTable, index, Function(flag) + Return Not flag + End Function) + If index >= 1 Then + primes.Add(index) + index += 1 + End If + Loop + End Sub + + Public Function GetAllPrimes() As Integer() + Return primes.ToArray() + End Function + + Public Function GetPrimesFrom(prime As Integer) As Integer() + Dim start As Integer = primes.FindIndex(Function(value) + Return value = prime + End Function) + If start < 0 Then + Throw New NotPrimeException(prime, String.Format("{0} is not a prime number.", prime)) + Else + Return primes.FindAll(Function(value) + Return value >= prime + End Function).ToArray() + End If + End Function +End Class +' \ No newline at end of file diff --git a/snippets/visualbasic/System/Exception/Overview/rethrow1.vb b/snippets/visualbasic/System/Exception/Overview/rethrow1.vb new file mode 100644 index 00000000000..03a035d95ed --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/rethrow1.vb @@ -0,0 +1,75 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic +Imports System.Runtime.CompilerServices + +Public Module Library + + Public Function FindOccurrences1(s As String, f As String) As Integer() + Dim indexes As New List(Of Integer) + Dim currentIndex As Integer = 0 + Try + Do While currentIndex >= 0 And currentIndex < s.Length + currentIndex = s.IndexOf(f, currentIndex) + If currentIndex >= 0 Then + indexes.Add(currentIndex) + currentIndex += 1 + End If + Loop + Catch e As ArgumentNullException + ' Perform some action here, such as logging this exception. + + Throw + End Try + Return indexes.ToArray() + End Function +End Module +' + +' +Module Example1 + Public Sub Main() + Dim s As String = "It was a cold day when..." + Dim indexes() As Integer = s.FindOccurrences1("a") + ShowOccurrences(s, "a", indexes) + Console.WriteLine() + + Dim toFind As String = Nothing + Try + indexes = s.FindOccurrences1(toFind) + ShowOccurrences(s, toFind, indexes) + Catch e As ArgumentNullException + Console.WriteLine("An exception ({0}) occurred.", + e.GetType().Name) + Console.WriteLine("Message:{0} {1}{0}", vbCrLf, e.Message) + Console.WriteLine("Stack Trace:{0} {1}{0}", vbCrLf, e.StackTrace) + End Try + End Sub + + Private Sub ShowOccurrences(s As String, toFind As String, indexes As Integer()) + Console.Write("'{0}' occurs at the following character positions: ", + toFind) + For ctr As Integer = 0 To indexes.Length - 1 + Console.Write("{0}{1}", indexes(ctr), + If(ctr = indexes.Length - 1, "", ", ")) + Next + Console.WriteLine() + End Sub +End Module +' The example displays the following output: +' 'a' occurs at the following character positions: 4, 7, 15 +' +' An exception (ArgumentNullException) occurred. +' Message: +' Value cannot be null. +' Parameter name: value +' +' Stack Trace: +' at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri +' ngComparison comparisonType) +' at Library.FindOccurrences(String s, String f) +' at Example.Main() +' + diff --git a/snippets/visualbasic/System/Exception/Overview/rethrow3.vb b/snippets/visualbasic/System/Exception/Overview/rethrow3.vb new file mode 100644 index 00000000000..07a74208c06 --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/rethrow3.vb @@ -0,0 +1,88 @@ +' Visual Basic .NET Document +Option Strict On + +Imports System.Collections.Generic +Imports System.Runtime.CompilerServices + +Public Module Library1 + + Public Function FindOccurrences(s As String, f As String) As Integer() + Dim indexes As New List(Of Integer) + Dim currentIndex As Integer = 0 + Try + Do While currentIndex >= 0 And currentIndex < s.Length + currentIndex = s.IndexOf(f, currentIndex) + If currentIndex >= 0 Then + indexes.Add(currentIndex) + currentIndex += 1 + End If + Loop + Catch e As ArgumentNullException + ' Perform some action here, such as logging this exception. + + ' + Throw New ArgumentNullException("You must supply a search string.", + e) + ' + End Try + Return indexes.ToArray() + End Function +End Module + +Module Example4 + Public Sub Main() + Dim s As String = "It was a cold day when..." + Dim indexes() As Integer = s.FindOccurrences("a") + ShowOccurrences(s, "a", indexes) + Console.WriteLine() + + Dim toFind As String = Nothing + ' + Try + indexes = s.FindOccurrences(toFind) + ShowOccurrences(s, toFind, indexes) + Catch e As ArgumentNullException + Console.WriteLine("An exception ({0}) occurred.", + e.GetType().Name) + Console.WriteLine(" Message: {1}{0}", vbCrLf, e.Message) + Console.WriteLine(" Stack Trace:{0} {1}{0}", vbCrLf, e.StackTrace) + Dim ie As Exception = e.InnerException + If ie IsNot Nothing Then + Console.WriteLine(" The Inner Exception:") + Console.WriteLine(" Exception Name: {0}", ie.GetType().Name) + Console.WriteLine(" Message: {1}{0}", vbCrLf, ie.Message) + Console.WriteLine(" Stack Trace:{0} {1}{0}", vbCrLf, ie.StackTrace) + End If + End Try + ' The example displays the following output: + ' 'a' occurs at the following character positions: 4, 7, 15 + ' + ' An exception (ArgumentNullException) occurred. + ' Message: You must supply a search string. + ' + ' Stack Trace: + ' at Library.FindOccurrences(String s, String f) + ' at Example.Main() + ' + ' The Inner Exception: + ' Exception Name: ArgumentNullException + ' Message: Value cannot be null. + ' Parameter name: value + ' + ' Stack Trace: + ' at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri + ' ngComparison comparisonType) + ' at Library.FindOccurrences(String s, String f) + ' + End Sub + + Private Sub ShowOccurrences(s As String, toFind As String, indexes As Integer()) + Console.Write("'{0}' occurs at the following character positions: ", + toFind) + For ctr As Integer = 0 To indexes.Length - 1 + Console.Write("{0}{1}", indexes(ctr), + If(ctr = indexes.Length - 1, "", ", ")) + Next + Console.WriteLine() + End Sub +End Module diff --git a/snippets/visualbasic/System/Exception/Overview/usageerrors1.vb b/snippets/visualbasic/System/Exception/Overview/usageerrors1.vb new file mode 100644 index 00000000000..0d91c47a2fa --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/usageerrors1.vb @@ -0,0 +1,35 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Class Person + Private _name As String + + Public Property Name As String + Get + Return _name + End Get + Set + _name = value + End Set + End Property + + Public Overrides Function Equals(obj As Object) As Boolean + ' This implementation contains an error in program logic: + ' It assumes that the obj argument is not null. + Dim p As Person = CType(obj, Person) + Return Me.Name.Equals(p.Name) + End Function +End Class + +Module Example2 + Public Sub Main() + Dim p1 As New Person() + p1.Name = "John" + Dim p2 As Person = Nothing + + ' The following throws a NullReferenceException. + Console.WriteLine("p1 = p2: {0}", p1.Equals(p2)) + End Sub +End Module +' diff --git a/snippets/visualbasic/System/Exception/Overview/usageerrors2.vb b/snippets/visualbasic/System/Exception/Overview/usageerrors2.vb new file mode 100644 index 00000000000..e6a7df307c2 --- /dev/null +++ b/snippets/visualbasic/System/Exception/Overview/usageerrors2.vb @@ -0,0 +1,39 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Class Person2 + Private _name As String + + Public Property Name As String + Get + Return _name + End Get + Set + _name = Value + End Set + End Property + + Public Overrides Function Equals(obj As Object) As Boolean + ' This implementation handles a null obj argument. + Dim p As Person2 = TryCast(obj, Person2) + If p Is Nothing Then + Return False + Else + Return Me.Name.Equals(p.Name) + End If + End Function +End Class + +Module Example3 + Public Sub Main() + Dim p1 As New Person2() + p1.Name = "John" + Dim p2 As Person2 = Nothing + + Console.WriteLine("p1 = p2: {0}", p1.Equals(p2)) + End Sub +End Module +' The example displays the following output: +' p1 = p2: False +' diff --git a/snippets/visualbasic/System/FlagsAttribute/Overview/Project.vbproj b/snippets/visualbasic/System/FlagsAttribute/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/FlagsAttribute/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/FlagsAttribute/Overview/flags.vb b/snippets/visualbasic/System/FlagsAttribute/Overview/flags.vb new file mode 100644 index 00000000000..805ad85c984 --- /dev/null +++ b/snippets/visualbasic/System/FlagsAttribute/Overview/flags.vb @@ -0,0 +1,77 @@ +' +Module Example + ' Define an Enum without FlagsAttribute. + Enum SingleHue As Short + None = 0 + Black = 1 + Red = 2 + Green = 4 + Blue = 8 + End Enum + + ' Define an Enum with FlagsAttribute. + + Enum MultiHue As Short + None = 0 + Black = 1 + Red = 2 + Green = 4 + Blue = 8 + End Enum + + Sub Main() + ' Display all possible combinations of values. + Console.WriteLine( + "All possible combinations of values without FlagsAttribute:") + For val As Integer = 0 To 16 + Console.WriteLine("{0,3} - {1:G}", val, CType(val, SingleHue)) + Next + Console.WriteLine() + + ' Display all combinations of values, and invalid values. + Console.WriteLine( + "All possible combinations of values with FlagsAttribute:") + For val As Integer = 0 To 16 + Console.WriteLine( "{0,3} - {1:G}", val, CType(val, MultiHue)) + Next + End Sub +End Module +' The example displays the following output: +' All possible combinations of values without FlagsAttribute: +' 0 - None +' 1 - Black +' 2 - Red +' 3 - 3 +' 4 - Green +' 5 - 5 +' 6 - 6 +' 7 - 7 +' 8 - Blue +' 9 - 9 +' 10 - 10 +' 11 - 11 +' 12 - 12 +' 13 - 13 +' 14 - 14 +' 15 - 15 +' 16 - 16 +' +' All possible combinations of values with FlagsAttribute: +' 0 - None +' 1 - Black +' 2 - Red +' 3 - Black, Red +' 4 - Green +' 5 - Black, Green +' 6 - Red, Green +' 7 - Black, Red, Green +' 8 - Blue +' 9 - Black, Blue +' 10 - Red, Blue +' 11 - Black, Red, Blue +' 12 - Green, Blue +' 13 - Black, Green, Blue +' 14 - Red, Green, Blue +' 15 - Black, Red, Green, Blue +' 16 - 16 +' \ No newline at end of file diff --git a/snippets/visualbasic/System/FlagsAttribute/Overview/flags1.vb b/snippets/visualbasic/System/FlagsAttribute/Overview/flags1.vb new file mode 100644 index 00000000000..45a8809f177 --- /dev/null +++ b/snippets/visualbasic/System/FlagsAttribute/Overview/flags1.vb @@ -0,0 +1,82 @@ +' Visual Basic .NET Document +Option Strict On + +' + +Public Enum PhoneService As Integer + None = 0 + LandLine = 1 + Cell = 2 + Fax = 4 + Internet = 8 + Other = 16 +End Enum + +Module Example1 + Public Sub Main() + ' Define three variables representing the types of phone service + ' in three households. + Dim household1 As PhoneService = PhoneService.LandLine Or + PhoneService.Cell Or + PhoneService.Internet + Dim household2 As PhoneService = PhoneService.None + Dim household3 As PhoneService = PhoneService.Cell Or + PhoneService.Internet + + ' Store the variables in an array for ease of access. + Dim households() As PhoneService = { household1, household2, + household3 } + + ' Which households have no service? + For ctr As Integer = 0 To households.Length - 1 + Console.WriteLine("Household {0} has phone service: {1}", + ctr + 1, + If(households(ctr) = PhoneService.None, + "No", "Yes")) + Next + Console.WriteLine() + + ' Which households have cell phone service? + For ctr As Integer = 0 To households.Length - 1 + Console.WriteLine("Household {0} has cell phone service: {1}", + ctr + 1, + If((households(ctr) And PhoneService.Cell) = PhoneService.Cell, + "Yes", "No")) + Next + Console.WriteLine() + + ' Which households have cell phones and land lines? + Dim cellAndLand As PhoneService = PhoneService.Cell Or PhoneService.LandLine + For ctr As Integer = 0 To households.Length - 1 + Console.WriteLine("Household {0} has cell and land line service: {1}", + ctr + 1, + If((households(ctr) And cellAndLand) = cellAndLand, + "Yes", "No")) + Next + Console.WriteLine() + + ' List all types of service of each household?' + For ctr As Integer = 0 To households.Length - 1 + Console.WriteLine("Household {0} has: {1:G}", + ctr + 1, households(ctr)) + Next + Console.WriteLine() + End Sub +End Module +' The example displays the following output: +' Household 1 has phone service: Yes +' Household 2 has phone service: No +' Household 3 has phone service: Yes +' +' Household 1 has cell phone service: Yes +' Household 2 has cell phone service: No +' Household 3 has cell phone service: Yes +' +' Household 1 has cell and land line service: Yes +' Household 2 has cell and land line service: No +' Household 3 has cell and land line service: No +' +' Household 1 has: LandLine, Cell, Internet +' Household 2 has: None +' Household 3 has: Cell, Internet +' diff --git a/xml/System/AccessViolationException.xml b/xml/System/AccessViolationException.xml index 9e1e4caf76f..0c382dd346f 100644 --- a/xml/System/AccessViolationException.xml +++ b/xml/System/AccessViolationException.xml @@ -50,7 +50,37 @@ The exception that is thrown when there is an attempt to read or write protected memory. - For more information about this API, see Supplemental API remarks for AccessViolationException. + + clearly identifies these serious errors. + +In programs that consist entirely of verifiable managed code, all references are either valid or null, and access violations are impossible. Any operation that attempts to reference a null reference in verifiable code throws a exception. An occurs only when verifiable managed code interacts with unmanaged code or with unsafe managed code. + +## Troubleshoot AccessViolationException exceptions + +An exception can occur only in unsafe managed code or when verifiable managed code interacts with unmanaged code: + +- An access violation that occurs in unsafe managed code can be expressed as either a exception or an exception, depending on the platform. +- An access violation in unmanaged code that bubbles up to managed code is always wrapped in an exception. + +In either case, you can identify and correct the cause of the exception as follows: + +- Make sure that the memory that you're attempting to access has been allocated. An exception is always thrown by an attempt to access protected memory—that is, to access memory that's not allocated or that's not owned by a process. + + Automatic memory management is one of the services that the .NET runtime provides. If managed code provides the same functionality as your unmanaged code, consider moving to managed code to take advantage of this functionality. For more information, see [Automatic memory management](/dotnet/standard/automatic-memory-management). + +- Make sure that the memory that you're attempting to access hasn't been corrupted. If several read or write operations have occurred through bad pointers, memory might be corrupted. This typically occurs when reading or writing to addresses outside of a predefined buffer. + +## AccessViolationException and try/catch blocks + + exceptions thrown by the .NET runtime aren't handled by the `catch` statement in a structured exception handler if the exception occurs outside of the memory reserved by the runtime. + +> [!CAUTION] +> The [HandleProcessCorruptedStateExceptions attribute](xref:System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute) is obsolete in current .NET versions. Recovery from corrupted process state–exceptions isn't supported, and the attribute, if present, is ignored. + + ]]> + Handling and Throwing Exceptions diff --git a/xml/System/Activator.xml b/xml/System/Activator.xml index 884c84b0455..cbf3e46a758 100644 --- a/xml/System/Activator.xml +++ b/xml/System/Activator.xml @@ -172,7 +172,7 @@ The constructor to be invoked must be accessible. > [!NOTE] -> This method can be used to access nonpublic types if the caller has been granted with the flag and if the grant set of the assembly that contains the nonpublic types is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) To use this functionality, your application should target .NET Framework 3.5 or later. +> This method can be used to access nonpublic types if the caller has been granted with the flag and if the grant set of the assembly that contains the nonpublic types is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) ## Examples The following code example demonstrates how to call the method. Instances of several different types are created and their default values are displayed. @@ -320,7 +320,7 @@ Assembly loads triggered by this API are affected by the current value of was compiled for a version of the CLR that is later than the currently loaded version. Note that the .NET Framework versions 2.0, 3.0, and 3.5 all use CLR version 2.0. + The common language runtime (CLR) version 2.0 or later is currently loaded, and was compiled for a version of the CLR that is later than the currently loaded version. An assembly or module was loaded twice with two different evidences. -or- @@ -389,16 +389,7 @@ Assembly loads triggered by this API are affected by the current value of if a public or nonpublic parameterless constructor can match; if only a public parameterless constructor can match. Creates an instance of the specified type using that type's parameterless constructor. A reference to the newly created object, or for instances. - - [!NOTE] -> This method can be used to access nonpublic types and members if the caller has been granted with the flag and if the grant set of the assembly that contains the nonpublic types and members is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) To use this functionality, your application should target .NET Framework 3.5 or later. - - ]]> - + To be added. is . @@ -499,11 +490,6 @@ Assembly loads triggered by this API are affected by the current value of [!NOTE] -> This method can be used to access nonpublic types if the caller has been granted with the flag and if the grant set of the assembly that contains the nonpublic types is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) To use this functionality, your application should target .NET Framework 3.5 or later. - - - ## Examples The following example calls the method to create a object. It calls the constructor to instantiate a string that contains ten elements from a character array starting at the fourteenth position. @@ -625,9 +611,6 @@ Assembly loads triggered by this API are affected by the current value of . -> [!NOTE] -> This method can be used to create nonpublic types if the caller has been granted with the flag and if the grant set of the nonpublic types is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) To use this functionality, your application should target .NET Framework 3.5 or later. - ]]> @@ -656,7 +639,7 @@ Assembly loads triggered by this API are affected by the current value of was compiled for a version of the CLR that is later than the currently loaded version. Note that the .NET Framework versions 2.0, 3.0, and 3.5 all use CLR version 2.0. + The common language runtime (CLR) version 2.0 or later is currently loaded, and was compiled for a version of the CLR that is later than the currently loaded version. An assembly or module was loaded twice with two different evidences. -or- @@ -736,9 +719,6 @@ An error occurred when attempting remote activation in a target specified in [!NOTE] -> This method can be used to access nonpublic types if the caller has been granted with the flag and if the grant set of the assembly that contains the nonpublic types is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) To use this functionality, your application should target .NET Framework 3.5 or later. - ]]> @@ -847,9 +827,6 @@ An error occurred when attempting remote activation in a target specified in [!NOTE] -> This method can be used to access nonpublic types and members if the caller has been granted with the flag and if the grant set of the assembly that contains the nonpublic types and members is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) To use this functionality, your application should target .NET Framework 3.5 or later. - ]]> @@ -958,9 +935,6 @@ An error occurred when attempting remote activation in a target specified in [!NOTE] -> This method can be used to access nonpublic types and members if the caller has been granted with the flag and if the grant set of the nonpublic types and members is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) To use this functionality, your application should target .NET Framework 3.5 or later. - ]]> @@ -1083,9 +1057,6 @@ An error occurred when attempting remote activation in a target specified in . -> [!NOTE] -> This method can be used to create nonpublic types and members if the caller has been granted with the flag and if the grant set of the assembly that contains the nonpublic types and members is restricted to the caller's grant set or to a subset thereof. (See [Security Considerations for Reflection](/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection).) To use this functionality, your application should target .NET Framework 3.5 or later. - ]]> @@ -1113,7 +1084,7 @@ Assembly loads triggered by this API are affected by the current value of was compiled for a version of the CLR that is later than the currently loaded version. Note that the .NET Framework versions 2.0, 3.0, and 3.5 all use CLR version 2.0. + The common language runtime (CLR) version 2.0 or later is currently loaded, and was compiled for a version of the CLR that is later than the currently loaded version. An assembly or module was loaded twice with two different evidences. -or- @@ -1296,7 +1267,7 @@ Assembly loads triggered by this API are affected by the current value of was compiled for a version of the CLR that is later than the currently loaded version. Note that the .NET Framework versions 2.0, 3.0, and 3.5 all use CLR version 2.0. + The common language runtime (CLR) version 2.0 or later is currently loaded, and was compiled for a version of the CLR that is later than the currently loaded version. @@ -1392,7 +1363,7 @@ Assembly loads triggered by this API are affected by the current value of was compiled for a version of the CLR that is later than the currently loaded version. Note that the .NET Framework versions 2.0, 3.0, and 3.5 all use CLR version 2.0. + The common language runtime (CLR) version 2.0 or later is currently loaded, and was compiled for a version of the CLR that is later than the currently loaded version. @@ -1498,7 +1469,7 @@ Assembly loads triggered by this API are affected by the current value of was compiled for a version of the CLR that is later than the currently loaded version. Note that the .NET Framework versions 2.0, 3.0, and 3.5 all use CLR version 2.0. + The common language runtime (CLR) version 2.0 or later is currently loaded, and was compiled for a version of the CLR that is later than the currently loaded version. diff --git a/xml/System/AppContext.xml b/xml/System/AppContext.xml index 126f23e1df1..7ad31e2dc6c 100644 --- a/xml/System/AppContext.xml +++ b/xml/System/AppContext.xml @@ -64,7 +64,84 @@ Provides members for setting and retrieving data about an application's context. - For more information about this API, see Supplemental API remarks for AppContext. + + class enables library writers to provide a uniform opt-out mechanism for new functionality for their users. It establishes a loosely coupled contract between components in order to communicate an opt-out request. This capability is typically important when a change is made to existing functionality. Conversely, there is already an implicit opt-in for new functionality. + +## AppContext for library developers + +Libraries use the class to define and expose compatibility switches, while library users can set those switches to affect the library behavior. By default, libraries provide the new functionality, and they only alter it (that is, they provide the previous functionality) if the switch is set. This allows libraries to provide new behavior for an existing API while continuing to support callers who depend on the previous behavior. + +### Define the switch name + +The most common way to allow consumers of your library to opt out of a change of behavior is to define a named switch. Its `value` element is a name/value pair that consists of the name of a switch and its value. By default, the switch is always implicitly `false`, which provides the new behavior (and makes the new behavior opt-in by default). Setting the switch to `true` enables it, which provides the legacy behavior. Explicitly setting the switch to `false` also provides the new behavior. + +It's beneficial to use a consistent format for switch names, since they're a formal contract exposed by a library. The following are two obvious formats: + +- *Switch*.*namespace*.*switchname* +- *Switch*.*library*.*switchname* + +Once you define and document the switch, callers can use it by calling the method programmatically. + +### Check the setting + +You can check if a consumer has declared the value of the switch and act appropriately by calling the method. The method returns `true` if the `switchName` argument is found, and its `isEnabled` argument indicates the value of the switch. Otherwise, the method returns `false`. + +### Example + +The following example illustrates the use of the class to allow the customer to choose the original behavior of a library method. The following is version 1.0 of a library named `StringLibrary`. It defines a `SubstringStartsAt` method that performs an ordinal comparison to determine the starting index of a substring within a larger string. + +:::code language="csharp" source="~/snippets/csharp/System/AppContext/Overview/V1/Example4.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/AppContext/Overview/Example4.fs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/AppContext/Overview/V1/Example4.vb" id="Snippet4"::: + +The following example then uses the library to find the starting index of the substring "archæ" in "The archaeologist". Because the method performs an ordinal comparison, the substring cannot be found. + +:::code language="csharp" source="~/snippets/csharp/System/AppContext/Overview/V1/Example4.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/AppContext/Overview/Example4.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/AppContext/Overview/V1/Example4.vb" id="Snippet5"::: + +Version 2.0 of the library, however, changes the `SubstringStartsAt` method to use culture-sensitive comparison. + +:::code language="csharp" source="~/snippets/csharp/System/AppContext/Overview/V2/Example6.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/AppContext/Overview/Example6.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/AppContext/Overview/V2/Example6.vb" id="Snippet6"::: + +When the app is recompiled to run against the new version of the library, it now reports that the substring "archæ" is found at index 4 in "The archaeologist". + +:::code language="csharp" source="~/snippets/csharp/System/AppContext/Overview/V2/Example6.cs" id="Snippet7"::: +:::code language="fsharp" source="~/snippets/fsharp/System/AppContext/Overview/Example6.fs" id="Snippet7"::: +:::code language="vb" source="~/snippets/visualbasic/System/AppContext/Overview/V2/Example6.vb" id="Snippet7"::: + +This change can be prevented from breaking the applications that depend on the original behavior by defining a switch. In this case, the switch is named `StringLibrary.DoNotUseCultureSensitiveComparison`. Its default value, `false`, indicates that the library should perform its version 2.0 culture-sensitive comparison. `true` indicates that the library should perform its version 1.0 ordinal comparison. A slight modification of the previous code allows the library consumer to set the switch to determine the kind of comparison the method performs. + +:::code language="csharp" source="~/snippets/csharp/System/AppContext/Overview/V3/Example8.cs" id="Snippet8"::: +:::code language="fsharp" source="~/snippets/fsharp/System/AppContext/Overview/Example8.fs" id="Snippet8"::: +:::code language="vb" source="~/snippets/visualbasic/System/AppContext/Overview/V3/Example8.vb" id="Snippet8"::: + +## AppContext for library consumers + +If you're the consumer of a library, the class allows you to take advantage of a library or library method's opt-out mechanism for new functionality. Individual methods of the class library that you are calling define particular switches that enable or disable a new behavior. The value of the switch is a Boolean. If it is `false`, which is typically the default value, the new behavior is enabled; if it is `true`, the new behavior is disabled, and the member behaves as it did previously. + +You can set the value of a switch by calling the method in your code. The `switchName` argument defines the switch name, and the `isEnabled` property defines the value of the switch. Because is a static class, it is available on a per-application domain basis. Calling the has application scope; that is, it affects only the application. + +For ASP.NET Core applications, you set a switch by adding an [``](/dotnet/framework/configure-apps/file-schema/appsettings/add-element-for-appsettings) element to the [``](/dotnet/framework/configure-apps/file-schema/appsettings/index) section of the web.config file. For example: + +```xml + + + + +``` + +If you set the same switch in more than one way, the order of precedence for determining which setting overrides the others is: + +1. The programmatic setting. +2. The setting in the web.config file (for ASP.NET Core apps). + + ]]> + diff --git a/xml/System/AppDomain.xml b/xml/System/AppDomain.xml index 34bda1e4285..8579042dbc2 100644 --- a/xml/System/AppDomain.xml +++ b/xml/System/AppDomain.xml @@ -2183,7 +2183,7 @@ The method. You can also execute assemblies using the method, which loads assemblies using the method. - - ## Examples The following sample demonstrates using one of the overloads of on two different domains. @@ -2451,7 +2449,7 @@ The method provides similar functionality to the method, but specifies the assembly by display name or rather than by file location. Therefore, loads assemblies with the method rather than with the method. - The assembly begins executing at the entry point specified in the .NET Framework header. + The assembly begins executing at the entry point specified in the .NET header. This method does not create a new process or application domain, and it does not execute the entry point method on a new thread. @@ -2534,7 +2532,7 @@ The method provides similar functionality to the method, but specifies the assembly by display name or rather than by file location. Therefore, loads assemblies with the method rather than with the method. - The assembly begins executing at the entry point specified in the .NET Framework header. + The assembly begins executing at the entry point specified in the .NET header. This method does not create a new process or application domain, and it does not execute the entry point method on a new thread. @@ -2611,7 +2609,7 @@ The method provides similar functionality to the method, but specifies the assembly by display name or rather than by file location. Therefore, loads assemblies with the method rather than with the method. - The assembly begins executing at the entry point specified in the .NET Framework header. + The assembly begins executing at the entry point specified in the .NET header. This method does not create a new process or application domain, and it does not execute the entry point method on a new thread. @@ -2900,7 +2898,7 @@ The friendly name of the default application domain is the file name of the proc property, which is stable even when the .NET Framework is hosted by an environment that supports fibers (that is, lightweight threads). + Use the property, which is stable even when .NET is hosted by an environment that supports fibers (that is, lightweight threads). ]]> @@ -3411,8 +3409,6 @@ The friendly name of the default application domain is the file name of the proc ## Remarks For information that is common to all overloads of this method, see the method overload. - Beginning with the .NET Framework 4, the trust level of an assembly that is loaded by using this method is the same as the trust level of the application domain. - ## Examples The following sample demonstrates the use of loading a raw assembly. @@ -3648,8 +3644,6 @@ The friendly name of the default application domain is the file name of the proc ## Remarks For information that is common to all overloads of this method, see the method overload. - Beginning with the .NET Framework 4, the trust level of an assembly that is loaded by using this method is the same as the trust level of the application domain. - ## Examples The following sample demonstrates the use of loading a raw assembly. @@ -4105,7 +4099,7 @@ This event is raised in each application domain that registers an event handler. > [!IMPORTANT] > This event is raised only for missing dependencies of the assembly that you are loading into the reflection-only context (for example, by using the method). It is not raised if the assembly that you are loading cannot be found. - Beginning with the .NET Framework 4, the property returns the assembly that requested the assembly load that could not be resolved. Knowing the identity of the requesting assembly might be useful in identifying the correct version of the dependency, if more than one version is available. For more information, see . +The property returns the assembly that requested the assembly load that could not be resolved. Knowing the identity of the requesting assembly might be useful in identifying the correct version of the dependency, if more than one version is available. For more information, see . For this event, the property returns the assembly name before policy is applied. @@ -4300,7 +4294,7 @@ This event is raised in each application domain that registers an event handler. > [!IMPORTANT] > This event is not raised if resolution fails because no file can be found for a valid linked resource. It is raised if a manifest resource stream cannot be found, but it is not raised if an individual resource key cannot be found. - Beginning with the .NET Framework 4, the property contains the assembly that requested the resource. For more information, see . +The property contains the assembly that requested the resource. For more information, see . To register an event handler for this event, you must have the required permissions, or a is thrown. @@ -5041,14 +5035,12 @@ This event is raised in each application domain that registers an event handler. However, the event does not occur if the runtime knows it is not possible to find a type in certain assemblies. For example, this event does not occur if the type is not found in a static assembly because the runtime knows types cannot be added dynamically to static assemblies. - Beginning with the .NET Framework 4, the property contains the assembly that requested the type. For more information, see . +The property contains the assembly that requested the type. For more information, see . To register an event handler for this event, you must have the required permissions, or a is thrown. For more information about handling events, see [Handling and Raising Events](/dotnet/standard/events/). - - ## Examples The following sample demonstrates the event. @@ -5113,11 +5105,39 @@ This event is raised in each application domain that registers an event handler. Occurs when an exception is not caught. - Handlers may be invoked multiple times if exceptions are thrown from different threads. - - For more information about this API, see Supplemental API remarks for UnhandledException. - event provides notification of uncaught exceptions. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application. If sufficient information about the state of the application is available, other actions may be undertaken - such as saving program data for later recovery. Caution is advised, because program data can become corrupted when exceptions are not handled. The handler will also be running while holding locks held when the exception was thrown, so care should be taken to avoid waiting on other resources which could introduce deadlocks. + +This event can be handled in any application domain. However, the event is not necessarily raised in the application domain where the exception occurred. An exception is unhandled only if the entire stack for the thread has been unwound without finding an applicable exception handler, so the first place the event can be raised is in the application domain where the thread originated. + +If the event is handled in the default application domain, it is raised there for any unhandled exception in any thread, no matter what application domain the thread started in. If the thread started in an application domain that has an event handler for , the event is raised in that application domain. If that application domain is not the default application domain, and there is also an event handler in the default application domain, the event is raised in both application domains. + +For example, suppose a thread starts in application domain "AD1", calls a method in application domain "AD2", and from there calls a method in application domain "AD3", where it throws an exception. The first application domain in which the event can be raised is "AD1". If that application domain is not the default application domain, the event can also be raised in the default application domain. + +> [!NOTE] +> The common language runtime suspends thread aborts while event handlers for the event are executing. + +If the event handler has a attribute with the appropriate flags, the event handler is treated as a constrained execution region. + +This event is not raised for exceptions that corrupt the state of the process, such as stack overflows or access violations, unless the event handler is security-critical and has the attribute. + +To register an event handler for this event, you must have the required permissions, or a is thrown. + +For more information about handling events, see [Handling and Raising Events](/dotnet/standard/events/index). + +## Other events for unhandled exceptions + +For certain application models, the event can be preempted by other events if the unhandled exception occurs in the main application thread. + +In applications that use Windows Forms, unhandled exceptions in the main application thread cause the event to be raised. If this event is handled, the default behavior is that the unhandled exception does not terminate the application, although the application is left in an unknown state. In that case, the event is not raised. This behavior can be changed by using the application configuration file, or by using the method to change the mode to before the event handler is hooked up. This applies only to the main application thread. The event is raised for unhandled exceptions thrown in other threads. + +The Visual Basic application framework provides another event for unhandled exceptions in the main application thread—the event. This event has an event arguments object with the same name as the event arguments object used by , but with different properties. In particular, this event arguments object has an property that allows the application to continue running, ignoring the unhandled exception (and leaving the application in an unknown state). In that case, the event is not raised. + +## Examples + The following example demonstrates the event. It defines an event handler, `MyHandler`, that is invoked whenever an unhandled exception is thrown in the default application domain. It then throws two exceptions. The first is handled by a **try/catch** block. The second is unhandled and invokes the `MyHandle` routine before the application terminates. :::code language="cpp" source="~/snippets/cpp/VS_Snippets_CLR/AppDomain_UnhandledException/CPP/unhandledexception.cpp" id="Snippet1"::: @@ -5125,7 +5145,7 @@ The following example demonstrates the - + diff --git a/xml/System/Array.xml b/xml/System/Array.xml index bdec11df88a..282fa73fb06 100644 --- a/xml/System/Array.xml +++ b/xml/System/Array.xml @@ -93,7 +93,7 @@ | The array size is limited to a total of 4 billion elements, and to a maximum index of 0X7FEFFFFF in any given dimension (0X7FFFFFC7 for byte arrays and arrays of single-byte structures). - Single-dimensional arrays implement the , , , and generic interfaces. The implementations are provided to arrays at run time, and as a result, the generic interfaces do not appear in the declaration syntax for the class. In addition, there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations). The key thing to be aware of when you cast an array to one of these interfaces is that members which add, insert, or remove elements throw . + Single-dimensional arrays implement the , , , , and generic interfaces. The implementations are provided to arrays at runtime, and as a result, the generic interfaces do not appear in the declaration syntax for the class. In addition, there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations). The key thing to be aware of when you cast an array to one of these interfaces is that members that add, insert, or remove elements throw . objects provide information about array type declarations. objects with the same array type share the same object. diff --git a/xml/System/Boolean.xml b/xml/System/Boolean.xml index b77e336d474..1dc094a0d2d 100644 --- a/xml/System/Boolean.xml +++ b/xml/System/Boolean.xml @@ -83,7 +83,155 @@ Represents a Boolean ( or ) value. - For more information about this API, see Supplemental API remarks for Boolean. + + instance can have either of two values: `true` or `false`. + +The structure provides methods that support the following tasks: + +- Converting Boolean values to strings: +- Parsing strings to convert them to Boolean values: and +- Comparing values: and + +This article explains these tasks and other usage details. + +## Format Boolean values + +The string representation of a is either "True" for a `true` value or "False" for a `false` value. The string representation of a value is defined by the read-only and fields. + +You use the method to convert Boolean values to strings. The Boolean structure includes two overloads: the parameterless method and the method, which includes a parameter that controls formatting. However, because this parameter is ignored, the two overloads produce identical strings. The method does not support culture-sensitive formatting. + +The following example illustrates formatting with the method. Note that the C# and VB examples use the [composite formatting](/dotnet/standard/base-types/composite-formatting) feature, while the F# example uses [string interpolation](/dotnet/fsharp/language-reference/interpolated-strings). In both cases the method is called implicitly. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/tostring1.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/tostring1.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/tostring1.vb" id="Snippet3"::: + +Because the structure can have only two values, it is easy to add custom formatting. For simple custom formatting in which other string literals are substituted for "True" and "False", you can use any conditional evaluation feature supported by your language, such as the [conditional operator](/dotnet/csharp/language-reference/operators/conditional-operator) in C# or the [If operator](/dotnet/visual-basic/language-reference/operators/if-operator) in Visual Basic. The following example uses this technique to format values as "Yes" and "No" rather than "True" and "False". + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/tostring2.cs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/tostring2.vb" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/tostring2.fs" id="Snippet4"::: + +For more complex custom formatting operations, including culture-sensitive formatting, you can call the method and provide an implementation. The following example implements the and interfaces to provide culture-sensitive Boolean strings for the English (United States), French (France), and Russian (Russia) cultures. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/format3.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/format3.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/format3.vb" id="Snippet5"::: + +Optionally, you can use [resource files](/dotnet/framework/resources/) to define culture-specific Boolean strings. + +## Convert to and from Boolean values + +The structure implements the interface. As a result, you can use the class to perform conversions between a value and any other primitive type in .NET, or you can call the structure's explicit implementations. However, conversions between a and the following types are not supported, so the corresponding conversion methods throw an exception: + +- Conversion between and (the and methods). + +- Conversion between and (the and methods). + +All conversions from integral or floating-point numbers to Boolean values convert non-zero values to `true` and zero values to `false`. The following example illustrates this by calling selected overloads of the class. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/conversion1.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/conversion1.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/conversion1.vb" id="Snippet6"::: + +When converting from Boolean to numeric values, the conversion methods of the class convert `true` to 1 and `false` to 0. However, Visual Basic conversion functions convert `true` to either 255 (for conversions to values) or -1 (for all other numeric conversions). The following example converts `true` to numeric values by using a method, and, in the case of the Visual Basic example, by using the Visual Basic language's own conversion operator. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/conversion3.cs" id="Snippet8"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/conversion3.fs" id="Snippet8"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/conversion3.vb" id="Snippet8"::: + +For conversions from to string values, see the [Format Boolean values](#format-boolean-values) section. For conversions from strings to values, see the [Parse Boolean values](#parse-boolean-values) section. + +## Parse Boolean values + +The structure includes two static parsing methods, and , that convert a string to a Boolean value. The string representation of a Boolean value is defined by the case-insensitive equivalents of the values of the and fields, which are "True" and "False", respectively. In other words, the only strings that parse successfully are "True", "False", "true", "false", or some mixed-case equivalent. You cannot successfully parse numeric strings such as "0" or "1". Leading or trailing white-space characters are not considered when performing the string comparison. + +The following example uses the and methods to parse a number of strings. Note that only the case-insensitive equivalents of "True" and "False" can be successfully parsed. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/parse2.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/parse2.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/parse2.vb" id="Snippet2"::: + +If you're programming in Visual Basic, you can use the `CBool` function to convert the string representation of a number to a Boolean value. "0" is converted to `false`, and the string representation of any non-zero value is converted to `true`. If you're not programming in Visual Basic, you must convert your numeric string to a number before converting it to a Boolean. The following example illustrates this by converting an array of integers to Boolean values. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/parse3.cs" id="Snippet9"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/parse3.fs" id="Snippet9"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/parse3.vb" id="Snippet9"::: + +## Compare Boolean values + +Because Boolean values are either `true` or `false`, there is little reason to explicitly call the method, which indicates whether an instance is greater than, less than, or equal to a specified value. Typically, to compare two Boolean variables, you call the method or use your language's equality operator. + +However, when you want to compare a Boolean variable with the literal Boolean value `true` or `false`, it's not necessary to do an explicit comparison, because the result of evaluating a Boolean value is that Boolean value. For example, the following two expressions are equivalent, but the second is more compact. However, both techniques offer comparable performance. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/operations1.cs" id="Snippet11"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/operations1.fs" id="Snippet11"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/operations1.vb" id="Snippet11"::: + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/operations1.cs" id="Snippet12"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/operations1.fs" id="Snippet12"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/operations1.vb" id="Snippet12"::: + +## Work with Booleans as binary values + +A Boolean value occupies one byte of memory, as the following example shows. The C# example must be compiled with the `/unsafe` switch. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/size1.cs" id="Snippet14"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/size1.fs" id="Snippet14"::: + +The byte's low-order bit is used to represent its value. A value of 1 represents `true`; a value of 0 represents `false`. + +> [!TIP] +> You can use the structure to work with sets of Boolean values. + +You can convert a Boolean value to its binary representation by calling the method. The method returns a byte array with a single element. To restore a Boolean value from its binary representation, you can call the method. + +The following example calls the method to convert a Boolean value to its binary representation and displays the individual bits of the value, and then calls the method to restore the value from its binary representation. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/binary1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/binary1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/binary1.vb" id="Snippet1"::: + +## Perform operations with Boolean values + +This section illustrates how Boolean values are used in apps. The first section discusses its use as a flag. The second illustrates its use for arithmetic operations. + +### Boolean values as flags + +Boolean variables are most commonly used as flags, to signal the presence or absence of some condition. For example, in the method, the final parameter, `ignoreCase`, is a flag that indicates whether the comparison of two strings is case-insensitive (`ignoreCase` is `true`) or case-sensitive (`ignoreCase` is `false`). The value of the flag can then be evaluated in a conditional statement. + +The following example uses a simple console app to illustrate the use of Boolean variables as flags. The app accepts command-line parameters that enable output to be redirected to a specified file (the `/f` switch), and that enable output to be sent both to a specified file and to the console (the `/b` switch). The app defines a flag named `isRedirected` to indicate whether output is to be sent to a file, and a flag named `isBoth` to indicate that output should be sent to the console. The F# example uses a [recursive function](/dotnet/fsharp/language-reference/functions/recursive-functions-the-rec-keyword) to parse the arguments. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/operations1.cs" id="Snippet10"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/operations1.fs" id="Snippet10"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/operations1.vb" id="Snippet10"::: + +### Booleans and arithmetic operations + +A Boolean value is sometimes used to indicate the presence of a condition that triggers a mathematical calculation. For example, a `hasShippingCharge` variable might serve as a flag to indicate whether to add shipping charges to an invoice amount. + +Because an operation with a `false` value has no effect on the result of an operation, it's not necessary to convert the Boolean to an integral value to use in the mathematical operation. Instead, you can use conditional logic. + +The following example computes an amount that consists of a subtotal, a shipping charge, and an optional service charge. The `hasServiceCharge` variable determines whether the service charge is applied. Instead of converting `hasServiceCharge` to a numeric value and multiplying it by the amount of the service charge, the example uses conditional logic to add the service charge amount if it is applicable. + +:::code language="csharp" source="~/snippets/csharp/System/Boolean/Overview/operations2.cs" id="Snippet13"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Boolean/Overview/operations2.fs" id="Snippet13"::: +:::code language="vb" source="~/snippets/visualbasic/System/Boolean/Overview/operations2.vb" id="Snippet13"::: + +### Booleans and interop + +While marshaling base data types to COM is generally straightforward, the data type is an exception. You can apply the attribute to marshal the type to any of the following representations: + +|Enumeration type|Unmanaged format| +|----------------------|----------------------| +||A 4-byte integer value, where any nonzero value represents `true` and 0 represents `false`. This is the default format of a field in a structure and of a parameter in platform invoke calls.| +||A 1-byte integer value, where the 1 represents `true` and 0 represents `false`.| +||A 2-byte integer value, where -1 represents `true` and 0 represents `false`. This is the default format of a parameter in COM interop calls.| + + ]]> + All members of this type are thread safe. Members that appear to modify instance state actually return a new instance initialized with the new value. As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety. diff --git a/xml/System/Byte.xml b/xml/System/Byte.xml index 155c5dc5840..25324635695 100644 --- a/xml/System/Byte.xml +++ b/xml/System/Byte.xml @@ -238,7 +238,83 @@ Represents an 8-bit unsigned integer. - For more information about this API, see Supplemental API remarks for Byte. + + is an immutable value type that represents unsigned integers with values that range from 0 (which is represented by the constant) to 255 (which is represented by the constant). .NET also includes a signed 8-bit integer value type, , which represents values that range from -128 to 127. + +## Instantiate a Byte value + +You can instantiate a value in several ways: + +- You can declare a variable and assign it a literal integer value that is within the range of the data type. The following example declares two variables and assigns them values in this way. + + :::code language="csharp" source="~/snippets/csharp/System/Byte/Overview/byteinstantiation1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Byte/Overview/byteinstantiation1.fs" id="Snippet1"::: + :::code language="vb" source="~/snippets/visualbasic/System/Byte/Overview/byteinstantiate1.vb" id="Snippet1"::: + +- You can assign a non-byte numeric value to a byte. This is a narrowing conversion, so it requires a cast operator in C# and F#, or a conversion method in Visual Basic if `Option Strict` is on. If the non-byte value is a , , or value that includes a fractional component, the handling of its fractional part depends on the compiler performing the conversion. The following example assigns several numeric values to variables. + + :::code language="csharp" source="~/snippets/csharp/System/Byte/Overview/byteinstantiation1.cs" id="Snippet2"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Byte/Overview/byteinstantiation1.fs" id="Snippet2"::: + :::code language="vb" source="~/snippets/visualbasic/System/Byte/Overview/byteinstantiate1.vb" id="Snippet2"::: + +- You can call a method of the class to convert any supported type to a value. This is possible because supports the interface. The following example illustrates the conversion of an array of values to values. + + :::code language="csharp" source="~/snippets/csharp/System/Byte/Overview/tobyte1.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Byte/Overview/tobyte1.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Convert/Overview/tobyte1.vb" id="Snippet4"::: + +- You can call the or method to convert the string representation of a value to a . The string can contain either decimal or hexadecimal digits. The following example illustrates the parse operation by using both a decimal and a hexadecimal string. + + :::code language="csharp" source="~/snippets/csharp/System/Byte/Overview/byteinstantiation1.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Byte/Overview/byteinstantiation1.fs" id="Snippet3"::: + :::code language="vb" source="~/snippets/visualbasic/System/Byte/Overview/byteinstantiate1.vb" id="Snippet3"::: + +## Perform operations on Byte values + +The type supports standard mathematical operations such as addition, subtraction, division, multiplication, subtraction, negation, and unary negation. Like the other integral types, the type also supports the bitwise `AND`, `OR`, `XOR`, left shift, and right shift operators. + +You can use the standard numeric operators to compare two values, or you can call the or method. + +You can also call the members of the class to perform a wide range of numeric operations, including getting the absolute value of a number, calculating the quotient and remainder from integral division, determining the maximum or minimum value of two integers, getting the sign of a number, and rounding a number. + +## Represent a Byte as a String + +The type provides full support for standard and custom numeric format strings. (For more information, see [Formatting Types](/dotnet/standard/base-types/formatting-types), [Standard Numeric Format Strings](/dotnet/standard/base-types/standard-numeric-format-strings), and [Custom Numeric Format Strings](/dotnet/standard/base-types/custom-numeric-format-strings).) However, most commonly, byte values are represented as one-digit to three-digit values without any additional formatting, or as two-digit hexadecimal values. + +To format a value as an integral string with no leading zeros, you can call the parameterless method. By using the "D" format specifier, you can also include a specified number of leading zeros in the string representation. By using the "X" format specifier, you can represent a value as a hexadecimal string. The following example formats the elements in an array of values in these three ways. + +:::code language="csharp" source="~/snippets/csharp/System/Byte/Overview/formatting1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Byte/Overview/formatting1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Byte/Overview/formatting1.vb" id="Snippet1"::: + +You can also format a value as a binary, octal, decimal, or hexadecimal string by calling the method and supplying the base as the method's second parameter. The following example calls this method to display the binary, octal, and hexadecimal representations of an array of byte values. + +:::code language="csharp" source="~/snippets/csharp/System/Byte/Overview/formatting1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Byte/Overview/formatting1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Byte/Overview/formatting1.vb" id="Snippet2"::: + +## Work with non-decimal Byte values + +In addition to working with individual bytes as decimal values, you might want to perform bitwise operations with byte values, or work with byte arrays or with the binary or hexadecimal representations of byte values. For example, overloads of the method can convert each of the primitive data types to a byte array, and the method converts a value to a byte array. + + values are represented in 8 bits by their magnitude only, without a sign bit. This is important to keep in mind when you perform bitwise operations on values or when you work with individual bits. To perform a numeric, Boolean, or comparison operation on any two non-decimal values, both values must use the same representation. + +When an operation is performed on two values, the values share the same representation, so the result is accurate. This is illustrated in the following example, which masks the lowest-order bit of a value to ensure that it is even. + +:::code language="csharp" source="~/snippets/csharp/System/Byte/Overview/bitwise1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Byte/Overview/bitwise1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Byte/Overview/bitwise1.vb" id="Snippet1"::: + +On the other hand, when you work with both unsigned and signed bits, bitwise operations are complicated by the fact that the values use sign-and-magnitude representation for positive values, and two's complement representation for negative values. In order to perform a meaningful bitwise operation, the values must be converted to two equivalent representations, and information about the sign bit must be preserved. The following example does this to mask out bits 2 and 4 of an array of 8-bit signed and unsigned values. + +:::code language="csharp" source="~/snippets/csharp/System/Byte/Overview/bitwise2.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Byte/Overview/bitwise2.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Byte/Overview/bitwise2.vb" id="Snippet2"::: + + ]]> + All members of this type are thread safe. Members that appear to modify instance state actually return a new instance initialized with the new value. As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety. diff --git a/xml/System/Char.xml b/xml/System/Char.xml index b49fb77744b..49ea64a1195 100644 --- a/xml/System/Char.xml +++ b/xml/System/Char.xml @@ -238,7 +238,96 @@ Represents a character as a UTF-16 code unit. - For more information about this API, see Supplemental API remarks for Char. + + structure represents Unicode code points by using UTF-16 encoding. The value of a object is its 16-bit numeric (ordinal) value. + +If you aren't familiar with Unicode, scalar values, code points, surrogate pairs, UTF-16, and the type, see [Introduction to character encoding in .NET](/dotnet/standard/base-types/character-encoding-introduction). + +This article examines the relationship between a object and a character and discuss some common tasks performed with instances. We recommend that you consider the type, introduced in .NET Core 3.0, as an alternative to for performing some of these tasks. + +## Char objects, Unicode characters, and strings + +A object is a sequential collection of structures that represents a string of text. Most Unicode characters can be represented by a single object, but a character that is encoded as a base character, surrogate pair, and/or combining character sequence is represented by multiple objects. For this reason, a structure in a object is not necessarily equivalent to a single Unicode character. + +Multiple 16-bit code units are used to represent single Unicode characters in the following cases: + +- Glyphs, which may consist of a single character or of a base character followed by one or more combining characters. For example, the character ä is represented by a object whose code unit is U+0061 followed by a object whose code unit is U+0308. (The character ä can also be defined by a single object that has a code unit of U+00E4.) The following example illustrates that the character ä consists of two objects. + + :::code language="csharp" source="~/snippets/csharp/System/Char/Overview/grapheme1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Char/Overview/grapheme1.fs" id="Snippet1"::: + :::code language="vb" source="~/snippets/visualbasic/System/Char/Overview/grapheme1.vb" id="Snippet1"::: + +- Characters outside the Unicode Basic Multilingual Plane (BMP). Unicode supports sixteen planes in addition to the BMP, which represents plane 0. A Unicode code point is represented in UTF-32 by a 21-bit value that includes the plane. For example, U+1D160 represents the MUSICAL SYMBOL EIGHTH NOTE character. Because UTF-16 encoding has only 16 bits, characters outside the BMP are represented by surrogate pairs in UTF-16. The following example illustrates that the UTF-32 equivalent of U+1D160, the MUSICAL SYMBOL EIGHTH NOTE character, is U+D834 U+DD60. U+D834 is the high surrogate; high surrogates range from U+D800 through U+DBFF. U+DD60 is the low surrogate; low surrogates range from U+DC00 through U+DFFF. + + :::code language="csharp" source="~/snippets/csharp/System/Char/Overview/surrogate1.cs" id="Snippet2"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Char/Overview/surrogate1.fs" id="Snippet2"::: + :::code language="vb" source="~/snippets/visualbasic/System/Char/Overview/surrogate1.vb" id="Snippet2"::: + +## Characters and character categories + +Each Unicode character or valid surrogate pair belongs to a Unicode category. In .NET, Unicode categories are represented by members of the enumeration and include values such as , , and , for example. + +To determine the Unicode category of a character, call the method. For example, the following example calls the to display the Unicode category of each character in a string. The example works correctly only if there are no surrogate pairs in the instance. + +:::code language="csharp" source="~/snippets/csharp/System/Char/Overview/GetUnicodeCategory3.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Char/Overview/GetUnicodeCategory3.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/Char/Overview/GetUnicodeCategory3.vb" id="Snippet6"::: + +Internally, for characters outside the ASCII range (U+0000 through U+00FF), the method depends on Unicode categories reported by the class. Unicode characters are classified based on [The Unicode Standard, Version 8.0.0](https://www.unicode.org/versions/Unicode8.0.0/). + +## Characters and text elements + +Because a single character can be represented by multiple objects, it is not always meaningful to work with individual objects. For instance, the following example converts the Unicode code points that represent the Aegean numbers zero through 9 to UTF-16 encoded code units. Because it erroneously equates objects with characters, it inaccurately reports that the resulting string has 20 characters. + +:::code language="csharp" source="~/snippets/csharp/System/Char/Overview/textelements2.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Char/Overview/textelements2.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/Char/Overview/textelements2.vb" id="Snippet3"::: + +You can do the following to avoid the assumption that a object represents a single character: + +- You can work with a object in its entirety instead of working with its individual characters to represent and analyze linguistic content. + +- You can use as shown in the following example: + + :::code language="csharp" source="~/snippets/csharp/System.Text/Rune/Overview/CountLettersInString.cs" id="SnippetGoodExample"::: + :::code language="fsharp" source="~/snippets/fsharp/System.Text/Rune/Overview/CountLettersInString.fs" id="SnippetGoodExample"::: + +- You can use the class to work with text elements instead of individual objects. The following example uses the object to count the number of text elements in a string that consists of the Aegean numbers zero through nine. Because it considers a surrogate pair a single character, it correctly reports that the string contains ten characters. + + :::code language="csharp" source="~/snippets/csharp/System/Char/Overview/textelements2a.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Char/Overview/textelements2a.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Char/Overview/textelements2a.vb" id="Snippet4"::: + +- If a string contains a base character that has one or more combining characters, you can call the method to convert the substring to a single UTF-16 encoded code unit. The following example calls the method to convert the base character U+0061 (LATIN SMALL LETTER A) and combining character U+0308 (COMBINING DIAERESIS) to U+00E4 (LATIN SMALL LETTER A WITH DIAERESIS). + + :::code language="csharp" source="~/snippets/csharp/System/Char/Overview/normalized.cs" id="Snippet5"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Char/Overview/normalized.fs" id="Snippet5"::: + :::code language="vb" source="~/snippets/visualbasic/System/Char/Overview/normalized.vb" id="Snippet5"::: + +## Common operations + +The structure provides methods to compare objects, convert the value of the current object to an object of another type, and determine the Unicode category of a object: + +|To do this|Use these `System.Char` methods| +|----------------|-------------------------------------| +|Compare objects| and | +|Convert a code point to a string|

See also the type.| +|Convert a object or a surrogate pair of objects to a code point|For a single character:

For a surrogate pair or a character in a string:

See also the type.| +|Get the Unicode category of a character|

See also .| +|Determine whether a character is in a particular Unicode category such as digit, letter, punctuation, control character, and so on|, , , , , , , , , , , , , , and

See also corresponding methods on the type.| +|Convert a object that represents a number to a numeric value type|

See also .| +|Convert a character in a string into a object| and | +|Convert a object to a object|| +|Change the case of a object|, , , and

See also corresponding methods on the type.| + +## Char values and interop + +When a managed type, which is represented as a Unicode UTF-16 encoded code unit, is passed to unmanaged code, the interop marshaller converts the character set to ANSI by default. You can apply the attribute to platform invoke declarations and the attribute to a COM interop declaration to control which character set a marshaled type uses. + + ]]>
+
. diff --git a/xml/System/Console.xml b/xml/System/Console.xml index d5006418517..419432bd77e 100644 --- a/xml/System/Console.xml +++ b/xml/System/Console.xml @@ -52,7 +52,144 @@ Represents the standard input, output, and error streams for console applications. This class cannot be inherited. - For more information about this API, see Supplemental API remarks for Console. + + class provides basic support for applications that read characters from, and write characters to, the console. + +## Console I/O streams + +When a console application starts, the operating system automatically associates three I/O streams with the console: standard input stream, standard output stream, and standard error output stream. Your application can read user input from the standard input stream; write normal data to the standard output stream; and write error data to the standard error output stream. These streams are presented to your application as the values of the , , and properties. + +By default, the value of the property is a object that represents the keyboard, and the values of the and properties are objects that represent a console window. However, you can set these properties to streams that do not represent the console window or keyboard; for example, you can set these properties to streams that represent files. To redirect the standard input, standard output, or standard error stream, call the , , or method, respectively. I/O operations that use these streams are synchronized, which means that multiple threads can read from, or write to, the streams. This means that methods that are ordinarily asynchronous, such as , execute synchronously if the object represents a console stream. + +> [!NOTE] +> Do not use the class to display output in unattended applications, such as server applications. Calls to methods such as and have no effect in GUI applications. + + class members that work normally when the underlying stream is directed to a console might throw an exception if the stream is redirected, for example, to a file. Program your application to catch exceptions if you redirect a standard stream. You can also use the , , and properties to determine whether a standard stream is redirected before performing an operation that throws an exception. + +It is sometimes useful to explicitly call the members of the stream objects represented by the , , and properties. For example, by default, the method reads input from the standard input stream. Similarly, the method writes data to the standard output stream, and the data is followed by the default line termination string, which can be found at . However, the class does not provide a corresponding method to write data to the standard error output stream, or a property to change the line termination string for data written to that stream. + +You can solve this problem by setting the property of the or property to another line termination string. For example, the following C# statement sets the line termination string for the standard error output stream to two carriage return and line feed sequences: + +`Console.Error.NewLine = "\r\n\r\n";` + +You can then explicitly call the method of the error output stream object, as in the following C# statement: + +`Console.Error.WriteLine();` + +## Screen buffer and console window + +Two closely related features of the console are the screen buffer and the console window. Text is actually read from or written to streams owned by the console, but appear to be read from or written to an area owned by the console called the screen buffer. The screen buffer is an attribute of the console, and is organized as a rectangular grid of rows and columns where each grid intersection, or character cell, can contain a character. Each character has its own foreground color, and each character cell has its own background color. + +The screen buffer is viewed through a rectangular region called the console window. The console window is another attribute of the console; it is not the console itself, which is an operating system window. The console window is arranged in rows and columns, is less than or equal to the size of the screen buffer, and can be moved to view different areas of the underlying screen buffer. If the screen buffer is larger than the console window, the console automatically displays scroll bars so the console window can be repositioned over the screen buffer area. + +A cursor indicates the screen buffer position where text is currently read or written. The cursor can be hidden or made visible, and its height can be changed. If the cursor is visible, the console window position is moved automatically so the cursor is always in view. + +The origin for character cell coordinates in the screen buffer is the upper left corner, and the positions of the cursor and the console window are measured relative to that origin. Use zero-based indexes to specify positions; that is, specify the topmost row as row 0, and the leftmost column as column 0. The maximum value for the row and column indexes is . + +## Unicode support for the console + +In general, the console reads input and writes output by using the current console code page, which the system locale defines by default. A code page can handle only a subset of available Unicode characters, so if you try to display characters that are not mapped by a particular code page, the console won't be able to display all characters or represent them accurately. The following example illustrates this problem. It tries to display the characters of the Cyrillic alphabet from U+0410 to U+044F to the console. If you run the example on a system that uses console code page 437, each character is replaced by a question mark (?), because Cyrillic characters do not map to the characters in code page 437. + +:::code language="csharp" source="~/snippets/csharp/System/Console/Overview/unicode1.cs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Console/Overview/unicode1.vb" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Console/Overview/unicode1.fs" id="Snippet1"::: + +In addition to supporting code pages, the class supports UTF-8 encoding with the class and UTF-16 encoding with the class. To display Unicode characters to the console. you set the property to either or . + +Support for Unicode characters requires the encoder to recognize a particular Unicode character, and also requires a font that has the glyphs needed to render that character. To successfully display Unicode characters to the console, the console font must be set to a non-raster or TrueType font such as Consolas or Lucida Console. The following example shows how you can programmatically change the font from a raster font to Lucida Console. + +:::code language="csharp" source="~/snippets/csharp/System/Console/Overview/setfont1.cs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/Console/Overview/setfont1.vb" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Console/Overview/setfont1.fs" id="Snippet3"::: + +However, TrueType fonts can display only a subset of glyphs. For example, the Lucida Console font displays only 643 of the approximately 64,000 available characters from U+0021 to U+FB02. To see which characters a particular font supports, open the **Fonts** applet in Control Panel, choose the **Find a character** option, and choose the font whose character set you'd like to examine in the **Font** list of the **Character Map** window. + +Windows uses font linking to display glyphs that are not available in a particular font. For information about font linking to display additional character sets, see [Globalization Step-by-Step: Fonts](https://go.microsoft.com/fwlink/?LinkId=229111). Linked fonts are defined in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink subkey of the registry. Each entry associated with this subkey corresponds to the name of a base font, and its value is a string array that defines the font files and the fonts that are linked to the base font. Each member of the array defines a linked font and takes the form *font-file-name*,*font-name*. The following example illustrates how you can programmatically define a linked font named SimSun found in a font file named simsun.ttc that displays Simplified Han characters. + +:::code language="csharp" source="~/snippets/csharp/System/Console/Overview/fontlink1.cs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Console/Overview/fontlink1.vb" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Console/Overview/fontlink1.fs" id="Snippet2"::: + +Unicode support for the console has the following limitations: + +- UTF-32 encoding is not supported. The only supported Unicode encodings are UTF-8 and UTF-16, which are represented by the and classes, respectively. + +- Bidirectional output is not supported. + +- Display of characters outside the Basic Multilingual Plane (that is, of surrogate pairs) is not supported, even if they are defined in a linked font file. + +- Display of characters in complex scripts is not supported. + +- Combining character sequences (that is, characters that consist of a base character and one or more combining characters) are displayed as separate characters. To work around this limitation, you can normalize the string to be displayed by calling the method before sending output to the console. In the following example, a string that contains the combining character sequence U+0061 U+0308 is displayed to the console as two characters before the output string is normalized, and as a single character after the method is called. + + :::code language="csharp" source="~/snippets/csharp/System/Console/Overview/normalize1.cs" id="Snippet5"::: + :::code language="vb" source="~/snippets/visualbasic/System/Console/Overview/normalize1.vb" id="Snippet5"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Console/Overview/normalize1.fs" id="Snippet5"::: + + Normalization is a viable solution only if the Unicode standard for the character includes a pre-composed form that corresponds to a particular combining character sequence. + +- If a font provides a glyph for a code point in the private use area, that glyph will be displayed. However, because characters in the private use area are application-specific, this may not be the expected glyph. + +The following example displays a range of Unicode characters to the console. The example accepts three command-line parameters: the start of the range to display, the end of the range to display, and whether to use the current console encoding (`false`) or UTF-16 encoding (`true`). It assumes that the console is using a TrueType font. + +:::code language="csharp" source="~/snippets/csharp/System/Console/Overview/example3.cs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/Console/Overview/example3.vb" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Console/Overview/example3.fs" id="Snippet4"::: + +## Common operations + +The class contains the following methods for reading console input and writing console output: + +- The overloads of the method read an individual character. + +- The method reads an entire line of input. + +- The method overloads convert an instance of a value type, an array of characters, or a set of objects to a formatted or unformatted string, and then write that string to the console. + +- A parallel set of method overloads output the same string as the overloads but also add a line termination string. + +The class also contains methods and properties to perform the following operations: + +- Get or set the size of the screen buffer. The and properties let you get or set the buffer height and width, respectively, and the method lets you set the buffer size in a single method call. + +- Get or set the size of the console window. The and properties let you get or set the window height and width, respectively, and the method lets you set the window size in a single method call. + +- Get or set the size of the cursor. The property specifies the height of the cursor in a character cell. + +- Get or set the position of the console window relative to the screen buffer. The and properties let you get or set the top row and leftmost column of the screen buffer that appears in the console window, and the method lets you set these values in a single method call. + +- Get or set the position of the cursor by getting or setting the and properties, or set the position of the cursor by calling the method. + +- Move or clear data in the screen buffer by calling the or method. + +- Get or set the foreground and background colors by using the and properties, or reset the background and foreground to their default colors by calling the method. + +- Play the sound of a beep through the console speaker by calling the method. + +## Default encodings + +In cases where .NET makes only a limited subset of code page encodings available, is used as the default encoding for the console. + +If your app depends on specific code page encodings, you can still make them available by doing the following *before* you call any methods: + +1. Retrieve the object from the property. + +2. Pass the object to the method to make the additional encodings supported by the encoding provider available. + +The class will then automatically use the default system encoding rather than UTF8, provided that you have registered the encoding provider before calling any output methods. + +## Examples + +The following example demonstrates how to read data from, and write data to, the standard input and output streams. Note that these streams can be redirected by using the and methods. + +:::code language="csharp" source="~/snippets/csharp/System/Console/Overview/source.cs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Console/Overview/source.vb" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Console/Overview/source.fs" id="Snippet1"::: + + ]]> + This type is thread safe. diff --git a/xml/System/Convert.xml b/xml/System/Convert.xml index a40ed5b1c35..adc20a9b315 100644 --- a/xml/System/Convert.xml +++ b/xml/System/Convert.xml @@ -64,7 +64,119 @@ Converts a base data type to another base data type. - For more information about this API, see Supplemental API remarks for Convert. + + class contains methods that are primarily used to support conversion to and from the base data types in .NET. The supported base types are , , , , , , , , , , , , , and . In addition, the class includes methods to support other kinds of conversions. + +## Conversions to and from base types + +A conversion method exists to convert every base type to every other base type. However, the actual call to a particular conversion method can produce one of five outcomes, depending on the value of the base type at runtime and the target base type. These five outcomes are: + +- No conversion. This occurs when an attempt is made to convert from a type to itself (for example, by calling with an argument of type ). In this case, the method simply returns an instance of the original type. + +- An . This occurs when a particular conversion is not supported. An is thrown for the following conversions: + + - Conversions from to , , , , or . + - Conversions from , , , , or to . + - Conversions from to any other type except . + - Conversions from any other type, except , to . + +- A . This occurs when the attempt to convert a string value to any other base type fails because the string is not in the proper format. The exception is thrown for the following conversions: + + - A string to be converted to a value does not equal or . + - A string to be converted to a value consists of multiple characters. + - A string to be converted to any numeric type is not recognized as a valid number. + - A string to be converted to a is not recognized as a valid date and time value. + +- A successful conversion. For conversions between two different base types not listed in the previous outcomes, all widening conversions as well as all narrowing conversions that do not result in a loss of data will succeed and the method will return a value of the targeted base type. + +- An . This occurs when a narrowing conversion results in a loss of data. For example, trying to convert a instance whose value is 10000 to a type throws an because 10000 is outside the range of the data type. + +An exception will not be thrown if the conversion of a numeric type results in a loss of precision (that is, the loss of some least significant digits). However, an exception will be thrown if the result is larger than can be represented by the particular conversion method's return value type. + +For example, when a is converted to a , a loss of precision might occur but no exception is thrown. However, if the magnitude of the is too large to be represented by a , an overflow exception is thrown. + +## Non-decimal numbers + +The class includes static methods that you can call to convert integral values to non-decimal string representations, and to convert strings that represent non-decimal numbers to integral values. Each of these conversion methods includes a `base` argument that lets you specify the number system; binary (base 2), octal (base 8), and hexadecimal (base 16), as well as decimal (base 10). There is a set of methods to convert each of the CLS-compliant primitive integral types to a string, and one to convert a string to each of the primitive integral types: + +- and , to convert a byte value to and from a string in a specified base. + +- and , to convert a 16-bit signed integer to and from a string in a specified base. + +- and , to convert a 32-bit signed integer to and from a string in a specified base. + +- and , to convert a 64-bit signed integer to and from a string in a specified base. + +- , to convert the string representation of a byte value in a specified format to a signed byte. + +- , to convert the string representation of an integer in a specified format to an unsigned 16-bit integer. + +- , to convert the string representation of an integer in a specified format to an unsigned 32-bit integer. + +- , to convert the string representation of an integer in a specified format to an unsigned 64-bit integer. + +The following example converts the value of to a string in all supported numeric formats. It then converts the string value back to a value. + +:::code language="csharp" source="~/snippets/csharp/System/Convert/Overview/NonDecimal1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Convert/Overview/NonDecimal1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Convert/Overview/NonDecimal1.vb" id="Snippet2"::: + +## Conversions from custom objects to base types + +In addition to supporting conversions between the base types, the method supports conversion of any custom type to any base type. To do this, the custom type must implement the interface, which defines methods for converting the implementing type to each of the base types. Conversions that are not supported by a particular type should throw an . + +When the method is passed a custom type as its first parameter, or when the `Convert.To`*Type* method (such as or is called and passed an instance of a custom type as its first parameter, the method, in turn, calls the custom type's implementation to perform the conversion. For more information, see [Type Conversion in .NET](/dotnet/standard/base-types/type-conversion). + +## Culture-specific formatting information + +All the base type conversion methods and the method include overloads that have a parameter of type . For example, the method has the following two overloads: + +- +- + +The parameter can supply culture-specific formatting information to assist the conversion process. However, it is ignored by most of the base type conversion methods. It is used only by the following base type conversion methods. If a `null` argument is passed to these methods, the object that represents the current culture is used. + +- By methods that convert a value to a numeric type. The parameter is used by the overload that has parameters of type and . It is also used by the overload that has parameters of type and if the object's runtime type is a . + +- By methods that convert a value to a date and time. The parameter is used by the overload that has parameters of type and . It is also used by the overload that has parameters of type and if the object's runtime type is a . + +- By the overloads that include an parameter and that convert either a numeric value to a string or a value to a string. + +However, any user-defined type that implements can make use of the parameter. + +## Base64 encoding + +Base64 encoding converts binary data to a string. Data expressed as base-64 digits can be easily conveyed over data channels that can only transmit 7-bit characters. The class includes the following methods to support base64 encoding: A set of methods support converting an array of bytes to and from a or to and from an array of Unicode characters consisting of base-64 digit characters. + +- , which converts a byte array to a base64-encoded string. +- , which converts a byte array to a base64-encoded character array. +- , which converts a base64-encoded string to a byte array. +- , which converts a base64-encoded character array to a byte array. + +## Other common conversions + +You can use other .NET classes to perform some conversions that aren't supported by the static methods of the class. These include: + +- Conversion to byte arrays + + The class provides methods that convert the primitive numeric types (including ) to byte arrays and from byte arrays back to primitive data types. + +- Character encoding and decoding + + The class and its derived classes (such as and ) provide methods to encode a character array or a string (that is, to convert them to a byte array in a particular encoding) and to decode an encoded byte array (that is, convert a byte array back to UTF16-encoded Unicode characters). For more information, see [Character Encoding in .NET](/dotnet/standard/base-types/character-encoding). + +## Examples + +The following example demonstrates some of the conversion methods in the class, including , , and . + +:::code language="csharp" source="~/snippets/csharp/System/Convert/Overview/converter.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Convert/Overview/converter.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Convert/Overview/converter.vb" id="Snippet1"::: + + ]]> + diff --git a/xml/System/DateTime.xml b/xml/System/DateTime.xml index 1e59e7b6ffd..4168e33a3d6 100644 --- a/xml/System/DateTime.xml +++ b/xml/System/DateTime.xml @@ -115,7 +115,401 @@ Represents an instant in time, typically expressed as a date and time of day. - For more information about this API, see Supplemental API remarks for DateTime. + + value type represents dates and times with values ranging from 00:00:00 (midnight), January 1, 0001 Anno Domini (Common Era) through 11:59:59 P.M., December 31, 9999 A.D. (C.E.) in the Gregorian calendar. + +Time values are measured in 100-nanosecond units called ticks. A particular date is the number of ticks since 12:00 midnight, January 1, 0001 A.D. (C.E.) in the calendar. The number excludes ticks that would be added by leap seconds. For example, a ticks value of 31241376000000000L represents the date Friday, January 01, 0100 12:00:00 midnight. A value is always expressed in the context of an explicit or default calendar. + +> [!NOTE] +> If you're working with a ticks value that you want to convert to some other time interval, such as minutes or seconds, you should use the , , , , or constant to perform the conversion. For example, to add the number of seconds represented by a specified number of ticks to the component of a value, you can use the expression `dateValue.Second + nTicks/Timespan.TicksPerSecond`. + +> [!NOTE] +> An alternative to the structure for working with date and time values in particular time zones is the structure. The structure stores date and time information in a private field and the number of minutes by which that date and time differs from UTC in a private field. This makes it possible for a value to reflect the time in a particular time zone, whereas a value can unambiguously reflect only UTC and the local time zone's time. For a discussion about when to use the structure or the structure when working with date and time values, see [Choosing Between DateTime, DateTimeOffset, TimeSpan, and TimeZoneInfo](/dotnet/standard/datetime/choosing-between-datetime). + +## Quick links to example code + +This article includes several examples that use the `DateTime` type: + +### Initialization examples + +- [Invoke a constructor](#initialization-01) +- [Invoke the implicit parameterless constructor](#initialization-02) +- [Assignment from return value](#initialization-03) +- [Parsing a string that represents a date and time](#initialization-04) +- [Visual Basic syntax to initialize a date and time](#initialization-05) + +### Format `DateTime` objects as strings examples + +- [Use the default date time format](#formatting-01) +- [Format a date and time using a specific culture](#formatting-02) +- [Format a date time using a standard or custom format string](#formatting-03) +- [Specify both a format string and a specific culture](#formatting-04) +- [Format a date time using the ISO 8601 standard for web services](#formatting-05) + +### Parse strings as `DateTime` objects examples + +- [Use `Parse` or `TryParse` to convert a string to a date and time](#parsing-01) +- [Use `ParseExact` or `TryParseExact` to convert a string in a known format](#parsing-02) +- [Convert from the ISO 8601 string representation to a date and time](#parsing-03) + +### `DateTime` resolution examples + +- [Explore the resolution of date and time values](#resolution-01) +- [Comparing for equality within a tolerance](#comparison-01) + +### Culture and calendars examples + +- [Display date and time values using culture specific calendars](#calendars-01) +- [Parse strings according to a culture specific calendar](#calendars-02) +- [Initialize a date and time from a specific culture's calendar](#calendars-03) +- [Accessing date and time properties using a specific culture's calendar](#calendars-04) +- [Retrieving the week of the year using culture specific calendars](#calendars-05) + +### Persistence examples + +- [Persisting date and time values as strings in the local time zone](#persistence-01) +- [Persisting date and time values as strings in a culture and time invariant format](#persistence-02) +- [Persisting date and time values as integers](#persistence-03) +- [Persisting date and time values using the `XmlSerializer`](#persistence-04) + +## Initialize a DateTime object + +You can assign an initial value to a new `DateTime` value in many different ways: + +- Calling a constructor, either one where you specify arguments for values, or use the implicit parameterless constructor. +- Assigning a `DateTime` to the return value of a property or method. +- Parsing a `DateTime` value from its string representation. +- Using Visual Basic-specific language features to instantiate a `DateTime`. + +The following code snippets show examples of each. + +### Invoke constructors + +You call any of the overloads of the constructor that specify elements of the date and time value (such as the year, month, and day, or the number of ticks). The following code creates a specific date using the constructor specifying the year, month, day, hour, minute, and second. + + +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Instantiation.vb" id="Snippet1"::: +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Instantiation.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Instantiation.fs" id="Snippet1"::: + +You invoke the `DateTime` structure's implicit parameterless constructor when you want a `DateTime` initialized to its default value. (For details on the implicit parameterless constructor of a value type, see [Value Types](/dotnet/csharp/language-reference/keywords/value-types).) Some compilers also support declaring a value without explicitly assigning a value to it. Creating a value without an explicit initialization also results in the default value. The following example illustrates the implicit parameterless constructor in C# and Visual Basic, as well as a declaration without assignment in Visual Basic. + + +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Instantiation.vb" id="Snippet5"::: +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Instantiation.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Instantiation.fs" id="Snippet5"::: + +### Assign a computed value + +You can assign the object a date and time value returned by a property or method. The following example assigns the current date and time, the current Coordinated Universal Time (UTC) date and time, and the current date to three new variables. + + +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Instantiation.vb" id="Snippet3"::: +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Instantiation.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Instantiation.fs" id="Snippet3"::: + +### Parse a string that represents a DateTime + +The , , , and methods all convert a string to its equivalent date and time value. The following examples use the and methods to parse a string and convert it to a value. The second format uses a form supported by the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) standard for a representing date and time in string format. This standard representation is often used to transfer date information in web services. + + +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Instantiation.vb" id="Snippet4"::: +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Instantiation.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Instantiation.fs" id="Snippet4"::: + +The and methods indicate whether a string is a valid representation of a value and, if it is, performs the conversion. + +### Language-specific syntax for Visual Basic + +The following Visual Basic statement initializes a new value. + + +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Instantiation.vb" id="Snippet2"::: + +## DateTime values and their string representations + +Internally, all values are represented as the number of ticks (the number of 100-nanosecond intervals) that have elapsed since 12:00:00 midnight, January 1, 0001. The actual value is independent of the way in which that value appears when displayed. The appearance of a value is the result of a formatting operation that converts a value to its string representation. + +The appearance of date and time values is dependent on culture, international standards, application requirements, and personal preference. The structure offers flexibility in formatting date and time values through overloads of . The default method returns the string representation of a date and time value using the current culture's short date and long time pattern. The following example uses the default method. It displays the date and time using the short date and long time pattern for the current culture. The en-US culture is the current culture on the computer on which the example was run. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/StringFormat.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/StringFormat.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/StringFormat.vb" id="Snippet1"::: + +You may need to format dates in a specific culture to support web scenarios where the server may be in a different culture from the client. You specify the culture using the method to create the short date and long time representation in a specific culture. The following example uses the method to display the date and time using the short date and long time pattern for the fr-FR culture. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/StringFormat.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/StringFormat.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/StringFormat.vb" id="Snippet2"::: + +Other applications may require different string representations of a date. The method returns the string representation defined by a standard or custom format specifier using the formatting conventions of the current culture. The following example uses the method to display the full date and time pattern for the en-US culture, the current culture on the computer on which the example was run. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/StringFormat.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/StringFormat.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/StringFormat.vb" id="Snippet3"::: + +Finally, you can specify both the culture and the format using the method. The following example uses the method to display the full date and time pattern for the fr-FR culture. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/StringFormat.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/StringFormat.fs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/StringFormat.vb" id="Snippet4"::: + +The overload can also be used with a custom format string to specify other formats. The following example shows how to format a string using the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) standard format often used for web services. The Iso 8601 format does not have a corresponding standard format string. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/StringFormat.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/StringFormat.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/StringFormat.vb" id="Snippet5"::: + +For more information about formatting values, see [Standard Date and Time Format Strings](/dotnet/standard/base-types/standard-date-and-time-format-strings) and [Custom Date and Time Format Strings](/dotnet/standard/base-types/custom-date-and-time-format-strings). + +## Parse DateTime values from strings + +Parsing converts the string representation of a date and time to a value. Typically, date and time strings have two different usages in applications: + +- A date and time takes a variety of forms and reflects the conventions of either the current culture or a specific culture. For example, an application allows a user whose current culture is en-US to input a date value as "12/15/2013" or "December 15, 2013". It allows a user whose current culture is en-gb to input a date value as "15/12/2013" or "15 December 2013." + +- A date and time is represented in a predefined format. For example, an application serializes a date as "20130103" independently of the culture on which the app is running. An application may require dates be input in the current culture's short date format. + +You use the or method to convert a string from one of the common date and time formats used by a culture to a value. The following example shows how you can use to convert date strings in different culture-specific formats to a value. It changes the current culture to English (United Kingdom) and calls the method to generate an array of date and time strings. It then passes each element in the array to the method. The output from the example shows the parsing method was able to successfully convert each of the culture-specific date and time strings. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Parsing.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Parsing.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Parsing.vb" id="Snippet1"::: + +You use the and methods to convert a string that must match a particular format or formats to a value. You specify one or more date and time format strings as a parameter to the parsing method. The following example uses the method to convert strings that must be either in a "yyyyMMdd" format or a "HHmmss" format to values. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Parsing.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Parsing.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Parsing.vb" id="Snippet2"::: + +One common use for is to convert a string representation from a web service, usually in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) standard format. The following code shows the correct format string to use: + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Parsing.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Parsing.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Parsing.vb" id="Snippet3"::: + +If a string cannot be parsed, the and methods throw an exception. The and methods return a value that indicates whether the conversion succeeded or failed. You should use the or methods in scenarios where performance is important. The parsing operation for date and time strings tends to have a high failure rate, and exception handling is expensive. Use these methods if strings are input by users or coming from an unknown source. + +For more information about parsing date and time values, see [Parsing Date and Time Strings](/dotnet/standard/base-types/parsing-datetime). + +## DateTime values + +Descriptions of time values in the type are often expressed using the Coordinated Universal Time (UTC) standard. Coordinated Universal Time is the internationally recognized name for Greenwich Mean Time (GMT). Coordinated Universal Time is the time as measured at zero degrees longitude, the UTC origin point. Daylight saving time is not applicable to UTC. + +Local time is relative to a particular time zone. A time zone is associated with a time zone offset. A time zone offset is the displacement of the time zone measured in hours from the UTC origin point. In addition, local time is optionally affected by daylight saving time, which adds or subtracts a time interval adjustment. Local time is calculated by adding the time zone offset to UTC and adjusting for daylight saving time if necessary. The time zone offset at the UTC origin point is zero. + +UTC time is suitable for calculations, comparisons, and storing dates and time in files. Local time is appropriate for display in user interfaces of desktop applications. Time zone-aware applications (such as many Web applications) also need to work with a number of other time zones. + +If the property of a object is , it is unspecified whether the time represented is local time, UTC time, or a time in some other time zone. + +## DateTime resolution + +> [!NOTE] +> As an alternative to performing date and time arithmetic on values to measure elapsed time, you can use the class. + +The property expresses date and time values in units of one ten-millionth of a second. The property returns the thousandths of a second in a date and time value. Using repeated calls to the property to measure elapsed time is dependent on the system clock. The system clock on Windows 7 and Windows 8 systems has a resolution of approximately 15 milliseconds. This resolution affects small time intervals less than 100 milliseconds. + +The following example illustrates the dependence of current date and time values on the resolution of the system clock. In the example, an outer loop repeats 20 times, and an inner loop serves to delay the outer loop. If the value of the outer loop counter is 10, a call to the method introduces a five-millisecond delay. The following example shows the number of milliseconds returned by the `DateTime.Now.Milliseconds` property changes only after the call to . + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Resolution.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Resolution.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Resolution.vb" id="Snippet1"::: + +## DateTime operations + +A calculation using a structure, such as or , does not modify the value of the structure. Instead, the calculation returns a new structure whose value is the result of the calculation. + +Conversion operations between time zones (such as between UTC and local time, or between one time zone and another) take daylight saving time into account, but arithmetic and comparison operations do not. + +The structure itself offers limited support for converting from one time zone to another. You can use the method to convert UTC to local time, or you can use the method to convert from local time to UTC. However, a full set of time zone conversion methods is available in the class. You convert the time in any one of the world's time zones to the time in any other time zone using these methods. + +Calculations and comparisons of objects are meaningful only if the objects represent times in the same time zone. You can use a object to represent a value's time zone, although the two are loosely coupled. A object does not have a property that returns an object that represents that date and time value's time zone. The property indicates if a `DateTime` represents UTC, local time, or is unspecified. In a time zone-aware application, you must rely on some external mechanism to determine the time zone in which a object was created. You could use a structure that wraps both the value and the object that represents the value's time zone. For details on using UTC in calculations and comparisons with values, see [Performing Arithmetic Operations with Dates and Times](/dotnet/standard/datetime/performing-arithmetic-operations). + +Each member implicitly uses the Gregorian calendar to perform its operation. Exceptions are methods that implicitly specify a calendar. These include constructors that specify a calendar, and methods with a parameter derived from , such as . + +Operations by members of the type take into account details such as leap years and the number of days in a month. + +## DateTime values and calendars + +The .NET Class Library includes a number of calendar classes, all of which are derived from the class. They are: + +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. +- The class. + +[!INCLUDE[japanese-era-note](~/includes/calendar-era.md)] + +Each culture uses a default calendar defined by its read-only property. Each culture may support one or more calendars defined by its read-only property. The calendar currently used by a specific object is defined by its property. It must be one of the calendars found in the array. + +A culture's current calendar is used in all formatting operations for that culture. For example, the default calendar of the Thai Buddhist culture is the Thai Buddhist Era calendar, which is represented by the class. When a object that represents the Thai Buddhist culture is used in a date and time formatting operation, the Thai Buddhist Era calendar is used by default. The Gregorian calendar is used only if the culture's property is changed, as the following example shows: + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Calendar.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Calendar.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Calendar.vb" id="Snippet1"::: + +A culture's current calendar is also used in all parsing operations for that culture, as the following example shows. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Calendar.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Calendar.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Calendar.vb" id="Snippet2"::: + +You instantiate a value using the date and time elements (number of the year, month, and day) of a specific calendar by calling a [DateTime constructor](xref:System.DateTime.%23ctor*) that includes a `calendar` parameter and passing it a object that represents that calendar. The following example uses the date and time elements from the calendar. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Calendar.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Calendar.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Calendar.vb" id="Snippet3"::: + + constructors that do not include a `calendar` parameter assume that the date and time elements are expressed as units in the Gregorian calendar. + +All other properties and methods use the Gregorian calendar. For example, the property returns the year in the Gregorian calendar, and the method assumes that the `year` parameter is a year in the Gregorian calendar. Each member that uses the Gregorian calendar has a corresponding member of the class that uses a specific calendar. For example, the method returns the year in a specific calendar, and the method interprets the `year` parameter as a year number in a specific calendar. The following example uses both the and the corresponding members of the class. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Calendar.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Calendar.fs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Calendar.vb" id="Snippet4"::: + +The structure includes a property that returns the day of the week in the Gregorian calendar. It does not include a member that allows you to retrieve the week number of the year. To retrieve the week of the year, call the individual calendar's method. The following example provides an illustration. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Calendar.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Calendar.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/Calendar.vb" id="Snippet5"::: + +For more information on dates and calendars, see [Working with Calendars](/dotnet/standard/datetime/working-with-calendars). + +## Persist DateTime values + +You can persist values in the following ways: + +- [Convert them to strings](#persist-values-as-strings) and persist the strings. +- [Convert them to 64-bit integer values](#persist-values-as-integers) (the value of the property) and persist the integers. +- [Serialize the DateTime values](#serializing-datetime-values). + +You must ensure that the routine that restores the values doesn't lose data or throw an exception regardless of which technique you choose. values should round-trip. That is, the original value and the restored value should be the same. And if the original value represents a single instant of time, it should identify the same moment of time when it's restored. + +### Persist values as strings + +To successfully restore values that are persisted as strings, follow these rules: + +- Make the same assumptions about culture-specific formatting when you restore the string as when you persisted it. To ensure that a string can be restored on a system whose current culture is different from the culture of the system it was saved on, call the overload to save the string by using the conventions of the invariant culture. Call the or overload to restore the string by using the conventions of the invariant culture. Never use the , , or overloads, which use the conventions of the current culture. + +- If the date represents a single moment of time, ensure that it represents the same moment in time when it's restored, even on a different time zone. Convert the value to Coordinated Universal Time (UTC) before saving it or use . + +The most common error made when persisting values as strings is to rely on the formatting conventions of the default or current culture. Problems arise if the current culture is different when saving and restoring the strings. The following example illustrates these problems. It saves five dates using the formatting conventions of the current culture, which in this case is English (United States). It restores the dates using the formatting conventions of a different culture, which in this case is English (United Kingdom). Because the formatting conventions of the two cultures are different, two of the dates can't be restored, and the remaining three dates are interpreted incorrectly. Also, if the original date and time values represent single moments in time, the restored times are incorrect because time zone information is lost. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Persistence.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Persistence.fs" id="Snippet1"::: + +To round-trip values successfully, follow these steps: + +1. If the values represent single moments of time, convert them from the local time to UTC by calling the method. +1. Convert the dates to their string representations by calling the or overload. Use the formatting conventions of the invariant culture by specifying as the `provider` argument. Specify that the value should round-trip by using the "O" or "R" standard format string. + +To restore the persisted values without data loss, follow these steps: + +1. Parse the data by calling the or overload. Specify as the `provider` argument, and use the same standard format string you used for the `format` argument during conversion. Include the value in the `styles` argument. +1. If the values represent single moments in time, call the method to convert the parsed date from UTC to local time. + +The following example uses the invariant culture and the "O" standard format string to ensure that values saved and restored represent the same moment in time regardless of the system, culture, or time zone of the source and target systems. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Persistence.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Persistence.fs" id="Snippet2"::: + +### Persist values as integers + +You can persist a date and time as an value that represents a number of ticks. In this case, you don't have to consider the culture of the systems the values are persisted and restored on. + +To persist a value as an integer: + +1. If the values represent single moments in time, convert them to UTC by calling the method. +1. Retrieve the number of ticks represented by the value from its property. + +To restore a value that has been persisted as an integer: + +1. Instantiate a new object by passing the value to the constructor. +1. If the value represents a single moment in time, convert it from UTC to the local time by calling the method. + +The following example persists an array of values as integers on a system in the U.S. Pacific Time zone. It restores it on a system in the UTC zone. The file that contains the integers includes an value that indicates the total number of values that immediately follow it. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Persistence.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Persistence.fs" id="Snippet3"::: + + + +### Serialize DateTime values + +You can persist values through serialization to a stream or file, and then restore them through deserialization. data is serialized in some specified object format. The objects are restored when they are deserialized. A formatter or serializer, such as or , handles the process of serialization and deserialization. For more information about serialization and the types of serialization supported by .NET, see [Serialization](/dotnet/standard/serialization/index). + +The following example uses the class to serialize and deserialize values. The values represent all leap year days in the twenty-first century. The output represents the result if the example is run on a system whose current culture is English (United Kingdom). Because you've deserialized the object itself, the code doesn't have to handle cultural differences in date and time formats. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/Persistence.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/Persistence.fs" id="Snippet4"::: + +The previous example doesn't include time information. If a value represents a moment in time and is expressed as a local time, convert it from local time to UTC before serializing it by calling the method. After you deserialize it, convert it from UTC to local time by calling the method. + +## DateTime vs. TimeSpan + +The and value types differ in that a represents an instant in time whereas a represents a time interval. You can subtract one instance of from another to obtain a object that represents the time interval between them. Or you could add a positive to the current to obtain a value that represents a future date. + +You can add or subtract a time interval from a object. Time intervals can be negative or positive, and they can be expressed in units such as ticks, seconds, or as a object. + +## Compare for equality within tolerance + +Equality comparisons for values are exact. To be considered equal, two values must be expressed as the same number of ticks. That precision is often unnecessary or even incorrect for many applications. Often, you want to test if objects are **roughly equal**. + +The following example demonstrates how to compare roughly equivalent values. It accepts a small margin of difference when declaring them equal. + + +:::code language="csharp" source="~/snippets/csharp/System/DateTime/Overview/DateTimeComparisons.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/DateTime/Overview/DateTimeComparisons.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/DateTime/Overview/DateTimeComparisons.vb" id="Snippet1"::: + +## COM interop considerations + +A value that is transferred to a COM application, then is transferred back to a managed application, is said to round-trip. However, a value that specifies only a time does not round-trip as you might expect. + +If you round-trip only a time, such as 3 P.M., the final date and time is December 30, 1899 C.E. at 3:00 P.M., instead of January, 1, 0001 C.E. at 3:00 P.M. .NET and COM assume a default date when only a time is specified. However, the COM system assumes a base date of December 30, 1899 C.E., while .NET assumes a base date of January, 1, 0001 C.E. + +When only a time is passed from .NET to COM, special processing is performed that converts the time to the format used by COM. When only a time is passed from COM to .NET, no special processing is performed because that would corrupt legitimate dates and times on or before December 30, 1899. If a date starts its round-trip from COM, .NET and COM preserve the date. + +The behavior of .NET and COM means that if your application round-trips a that only specifies a time, your application must remember to modify or ignore the erroneous date from the final object. + + ]]> + All members of this type are thread safe. Members that appear to modify instance state actually return a new instance initialized with the new value. As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety. @@ -451,8 +845,6 @@ The namespace provides several calendars including and . - - ## Examples The following example calls the constructor twice to instantiate two values. The first call instantiates a value by using a object. Because the Persian calendar cannot be designated as the default calendar for a culture, displaying a date in the Persian calendar requires individual calls to its , , and methods. The second call to the constructor instantiates a value by using a object. The example changes the current culture to Arabic (Syria) and changes the current culture's default calendar to the Hijri calendar. Because Hijri is the current culture's default calendar, the method uses it to format the date. When the previous current culture (which is English (United States) in this case) is restored, the method uses the current culture's default Gregorian calendar to format the date. @@ -732,8 +1124,6 @@ The namespace provides several calendars including and . - - ## Examples The following example calls the constructor twice to instantiate two values. The first call instantiates a value by using a object. Because the Persian calendar cannot be designated as the default calendar for a culture, displaying a date in the Persian calendar requires individual calls to its , , and methods. The second call to the constructor instantiates a value by using a object. The example changes the current culture to Arabic (Syria) and changes the current culture's default calendar to the Hijri calendar. Because Hijri is the current culture's default calendar, the method uses it to format the date. When the previous current culture (which is English (United States) in this case) is restored, the method uses the current culture's default Gregorian calendar to format the date. @@ -1042,8 +1432,6 @@ The namespace provides several calendars including and . - - ## Examples The following example calls the constructor twice to instantiate two values. The first call instantiates a value by using a object. Because the Persian calendar cannot be designated as the default calendar for a culture, displaying a date in the Persian calendar requires individual calls to its , , and methods. The second call to the constructor instantiates a value by using a object. The example changes the current culture to Arabic (Syria) and changes the current culture's default calendar to the Hijri calendar. Because Hijri is the current culture's default calendar, the method uses it to format the date. When the previous current culture (which is English (United States) in this case) is restored, the method uses the current culture's default Gregorian calendar to format the date. @@ -1238,8 +1626,6 @@ For applications in which portability of date and time data or a limited degree The namespace provides several calendars including and . - - ## Examples The following example calls the constructor twice to instantiate two values. The first call instantiates a value by using a object. Because the Persian calendar cannot be designated as the default calendar for a culture, displaying a date in the Persian calendar requires individual calls to its , , and methods. The second call to the constructor instantiates a value by using a object. The example changes the current culture to Arabic (Syria) and changes the current culture's default calendar to the Hijri calendar. Because Hijri is the current culture's default calendar, the method uses it to format the date. When the previous current culture (which is English (United States) in this case) is restored, the method uses the current culture's default Gregorian calendar to format the date. @@ -3179,7 +3565,34 @@ The full precision of the `value` parameter is used. Howeve A 64-bit signed integer that encodes the property in a 2-bit field and the property in a 62-bit field. Deserializes a 64-bit binary value and recreates an original serialized object. An object that is equivalent to the object that was serialized by the method. - For more information about this API, see Supplemental API remarks for DateTime.FromBinary. + + method to convert the value of the current object to a binary value. Subsequently, use the binary value and the method to recreate the original object. + +> [!IMPORTANT] +> In some cases, the value returned by the method is not identical to the original value supplied to the method. For more information, see the next section, "Local Time Adjustment". + +A structure consists of a private field, which indicates whether the specified time value is based on local time, Coordinated Universal Time (UTC), or neither, concatenated to a private field, which contains the number of 100-nanosecond ticks that specify a date and time. + +## Local time adjustment + +A local time, which is a Coordinated Universal Time adjusted to the local time zone, is represented by a structure whose property has the value . When restoring a local value from the binary representation that is produced by the method, the method may adjust the recreated value so that it is not equal to the original value. This can occur under the following conditions: + +- If a local object is serialized in one time zone by the method, and then deserialized in a different time zone by the method, the local time represented by the resulting object is automatically adjusted to the second time zone. + + For example, consider a object that represents a local time of 3 P.M. An application that is executing in the U.S. Pacific Time zone uses the method to convert that object to a binary value. Another application that is executing in the U.S. Eastern Time zone then uses the method to convert the binary value to a new object. The value of the new object is 6 P.M., which represents the same point in time as the original 3 P.M. value, but is adjusted to local time in the Eastern Time zone. + +- If the binary representation of a local value represents an invalid time in the local time zone of the system on which is called, the time is adjusted so that it is valid. + + For example, the transition from standard time to daylight saving time occurs in the Pacific Time zone of the United States on March 14, 2010, at 2:00 A.M., when the time advances by one hour, to 3:00 A.M. This hour interval is an invalid time, that is, a time interval that does not exist in this time zone. The following example shows that when a time that falls within this range is converted to a binary value by the method and is then restored by the method, the original value is adjusted to become a valid time. You can determine whether a particular date and time value may be subject to modification by passing it to the method, as the example illustrates. + + :::code language="csharp" source="~/snippets/csharp/System/DateTime/FromBinary/frombinary1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/DateTime/FromBinary/frombinary1.fs" id="Snippet1"::: + :::code language="vb" source="~/snippets/visualbasic/System/DateTime/FromBinary/frombinary1.vb" id="Snippet1"::: + + ]]> + is less than DateTime.MinValue or greater than DateTime.MaxValue. @@ -5399,8 +5812,8 @@ The following example parses strings in each of these formats by using the forma [!INCLUDE[japanese-era-note](~/includes/calendar-era.md)] -|If you call|And `provider` is|Formatting information is derived from| -|-----------------|-----------------------|--------------------------------------------| +| If you call | And `provider` is | Formatting information is derived from | +|-------------|-------------------|----------------------------------------| ||-|The current culture ( property)| | or |a object|The specified object| | or |`null`|The current culture ( property)| @@ -7760,7 +8173,34 @@ In general, the ticks represent the time according to the time zone specified by Serializes the current object to a 64-bit binary value that subsequently can be used to recreate the object. A 64-bit signed integer that encodes the and properties. - For more information about this API, see Supplemental API remarks for DateTime.ToBinary. + + method to convert the value of the current object to a binary value. Subsequently, use the binary value and the method to recreate the original object. + +> [!IMPORTANT] +> In some cases, the value returned by the method is not identical to the original value supplied to the method. For more information, see the next section, "Local Time Adjustment". + +A structure consists of a private field, which indicates whether the specified time value is based on local time, Coordinated Universal Time (UTC), or neither, concatenated to a private field, which contains the number of 100-nanosecond ticks that specify a date and time. + +## Local time adjustment + +A local time, which is a Coordinated Universal Time adjusted to the local time zone, is represented by a structure whose property has the value . When restoring a local value from the binary representation that is produced by the method, the method may adjust the recreated value so that it is not equal to the original value. This can occur under the following conditions: + +- If a local object is serialized in one time zone by the method, and then deserialized in a different time zone by the method, the local time represented by the resulting object is automatically adjusted to the second time zone. + + For example, consider a object that represents a local time of 3 P.M. An application that is executing in the U.S. Pacific Time zone uses the method to convert that object to a binary value. Another application that is executing in the U.S. Eastern Time zone then uses the method to convert the binary value to a new object. The value of the new object is 6 P.M., which represents the same point in time as the original 3 P.M. value, but is adjusted to local time in the Eastern Time zone. + +- If the binary representation of a local value represents an invalid time in the local time zone of the system on which is called, the time is adjusted so that it is valid. + + For example, the transition from standard time to daylight saving time occurs in the Pacific Time zone of the United States on March 14, 2010, at 2:00 A.M., when the time advances by one hour, to 3:00 A.M. This hour interval is an invalid time, that is, a time interval that does not exist in this time zone. The following example shows that when a time that falls within this range is converted to a binary value by the method and is then restored by the method, the original value is adjusted to become a valid time. You can determine whether a particular date and time value may be subject to modification by passing it to the method, as the example illustrates. + + :::code language="csharp" source="~/snippets/csharp/System/DateTime/FromBinary/frombinary1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/DateTime/FromBinary/frombinary1.fs" id="Snippet1"::: + :::code language="vb" source="~/snippets/visualbasic/System/DateTime/FromBinary/frombinary1.vb" id="Snippet1"::: + + ]]> +
@@ -9373,7 +9813,52 @@ The value returned by the method is dete Converts the specified string representation of a date and time to its equivalent using the specified culture-specific format information and formatting style, and returns a value that indicates whether the conversion succeeded. if the parameter was converted successfully; otherwise, . - For more information about this API, see Supplemental API remarks for DateTime.TryParse. + + method parses a string that can contain date, time, and time zone information. It is similar to the method, except that the method does not throw an exception if the conversion fails. + +This method attempts to ignore unrecognized data and parse the input string (`s`) completely. If `s` contains a time but no date, the method by default substitutes the current date or, if `styles` includes the flag, it substitutes `DateTime.Date.MinValue`. If `s` contains a date but no time, 12:00 midnight is used as the default time. If a date is present but its year component consists of only two digits, it is converted to a year in the `provider` parameter's current calendar based on the value of the property. Any leading, inner, or trailing white space characters in `s` are ignored. The date and time can be bracketed with a pair of leading and trailing NUMBER SIGN characters ('#', U+0023), and can be trailed with one or more NULL characters (U+0000). + +Specific valid formats for date and time elements, as well as the names and symbols used in dates and times, are defined by the `provider` parameter, which can be any of the following: + +- A object that represents the culture whose formatting is used in the `s` parameter. The object returned by the property defines the formatting used in `s`. +- A object that defines the formatting used in `s`. +- A custom implementation. Its method returns a object that defines the formatting used in `s`. + +If `provider` is `null`, the current culture is used. + +If `s` is the string representation of a leap day in a leap year in the current calendar, the method parses `s` successfully. If `s` is the string representation of a leap day in a non-leap year in the current calendar of `provider`, the parse operation fails and the method returns `false`. + +The `styles` parameter defines the precise interpretation of the parsed string and how the parse operation should handle it. It can be one or more members of the enumeration, as described in the following table. + +|DateTimeStyles member|Description| +|---------------------------|-----------------| +||Parses `s` and, if necessary, converts it to UTC. If `s` includes a time zone offset, or if `s` contains no time zone information but `styles` includes the flag, the method parses the string, calls to convert the returned value to UTC, and sets the property to . If `s` indicates that it represents UTC, or if `s` does not contain time zone information but `styles` includes the flag, the method parses the string, performs no time zone conversion on the returned value, and sets the property to . In all other cases, the flag has no effect.| +||Although valid, this value is ignored. Inner white space is permitted in the date and time elements of `s`.| +||Although valid, this value is ignored. Leading white space is permitted in the date and time elements of `s`.| +||Although valid, this value is ignored. Trailing white space is permitted in the date and time elements of `s`.| +||Specifies that `s` may contain leading, inner, and trailing white spaces. This is the default behavior. It cannot be overridden by supplying a more restrictive enumeration value such as .| +||Specifies that if `s` lacks any time zone information, it is assumed to represent a local time. Unless the flag is present, the property of the returned value is set to .| +||Specifies that if `s` lacks any time zone information, it is assumed to represent UTC. Unless the flag is present, the method converts the returned value from UTC to local time and sets its property to .| +||Although valid, this value is ignored.| +||For strings that contain time zone information, tries to prevent the conversion of a date and time string to a value with its property set to . Typically, such a string is created by calling the method using either the "o", "r", or "u" standard format specifiers.| + +If `s` contains no time zone information, the method returns a value whose property is unless a `styles` flag indicates otherwise. If `s` includes time zone or time zone offset information, the method performs any necessary time conversion and returns one of the following: + +- A value whose date and time reflect the local time and whose property is . +- Or, if `styles` includes the flag, a value whose date and time reflect UTC and whose property is . + +This behavior can be overridden by using the flag. + +## Parse custom cultures + +If you parse a date and time string generated for a custom culture, use the method instead of the method to improve the probability that the parse operation will succeed. A custom culture date and time string can be complicated and difficult to parse. The method attempts to parse a string with several implicit parse patterns, all of which might fail. In contrast, the method requires you to explicitly designate one or more exact parse patterns that are likely to succeed. + +For more information about custom cultures, see the class. + + ]]> + method. diff --git a/xml/System/Decimal.xml b/xml/System/Decimal.xml index e3cc6da57fc..52942672959 100644 --- a/xml/System/Decimal.xml +++ b/xml/System/Decimal.xml @@ -245,7 +245,55 @@ Represents a decimal floating-point number. - For more information about this API, see Supplemental API remarks for Decimal. + + value type represents decimal numbers ranging from positive 79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335. The default value of a `Decimal` is 0. The value type is appropriate for financial calculations that require large numbers of significant integral and fractional digits and no round-off errors. The type does not eliminate the need for rounding. Rather, it minimizes errors due to rounding. For example, the following code produces a result of 0.9999999999999999999999999999 instead of 1. + +:::code language="csharp" source="~/snippets/csharp/System/Decimal/Overview/DecimalDivision_46630_1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Decimal/Overview/DecimalDivision_46630_1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Decimal/Overview/DecimalDivision_46630_1.vb" id="Snippet1"::: + +When the result of the division and multiplication is passed to the method, the result suffers no loss of precision, as the following code shows. + +:::code language="csharp" source="~/snippets/csharp/System/Decimal/Overview/DecimalDivision_46630_1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Decimal/Overview/DecimalDivision_46630_1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Decimal/Overview/DecimalDivision_46630_1.vb" id="Snippet2"::: + +A decimal number is a floating-point value that consists of a sign, a numeric value where each digit in the value ranges from 0 to 9, and a scaling factor that indicates the position of a floating decimal point that separates the integral and fractional parts of the numeric value. + +The binary representation of a `Decimal` value is 128-bits consisting of a 96-bit integer number, and a 32-bit set of flags representing things such as the sign and scaling factor used to specify what portion of it is a decimal fraction. Therefore, the binary representation of a value the form, ((-296 to 296) / 10(0 to 28)), where -(296-1) is equal to , and 296-1 is equal to . For more information about the binary representation of values and an example, see the constructor and the method. + +The scaling factor also preserves any trailing zeros in a number. Trailing zeros do not affect the value of a number in arithmetic or comparison operations. However, trailing zeros might be revealed by the method if an appropriate format string is applied. + +## Conversion considerations + +This type provides methods that convert values to and from , , , , , , , and values. Conversions from these integral types to are widening conversions that never lose information or throw exceptions. + +Conversions from to any of the integral types are narrowing conversions that round the value to the nearest integer value toward zero. Some languages, such as C#, also support the conversion of values to values. If the result of these conversions cannot be represented in the destination type, an exception is thrown. + +The type also provides methods that convert values to and from and values. Conversions from to or are narrowing conversions that might lose precision but not information about the magnitude of the converted value. The conversion does not throw an exception. + +Conversions from or to throw an exception if the result of the conversion cannot be represented as a . + +## Perform operations on Decimal values + +The type supports standard mathematical operations such as addition, subtraction, division, multiplication, and unary negation. You can also work directly with the binary representation of a value by calling the method. + +To compare two values, you can use the standard numeric comparison operators, or you can call the or method. + +You can also call the members of the class to perform a wide range of numeric operations, including getting the absolute value of a number, determining the maximum or minimum value of two values, getting the sign of a number, and rounding a number. + +## Examples + +The following code example demonstrates the use of . + +:::code language="csharp" source="~/snippets/csharp/System/Decimal/Overview/source.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Decimal/Overview/source.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Decimal/Overview/source.vb" id="Snippet1"::: + + ]]> + All members of this type are thread safe. Members that appear to modify instance state actually return a new instance initialized with the new value. As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety. diff --git a/xml/System/Delegate.xml b/xml/System/Delegate.xml index 52d53ab3660..87fcb1d4dba 100644 --- a/xml/System/Delegate.xml +++ b/xml/System/Delegate.xml @@ -113,7 +113,116 @@ Generic delegate types can have variant type parameters. Contravariant type para The closest equivalent of a delegate in C is a function pointer. A delegate can represent a static method or an instance method. When the delegate represents an instance method, the delegate stores not only a reference to the method's entry point, but also a reference to the class instance. Unlike function pointers, delegates are object oriented and type safe. -For examples, see [Supplemental API remarks for System.Delegate.CreateDelegate](/dotnet/fundamentals/runtime-libraries/system-delegate-createdelegate). +## CreateDelegate examples + +The methods create a delegate of a specified type. + +### method + +This method overload is equivalent to calling the method overload and specifying `true` for `throwOnBindFailure`. + +#### Examples + +This section contains two code examples. The first example demonstrates the two kinds of delegates that can be created with this method overload: open over an instance method and open over a static method. + +The second code example demonstrates compatible parameter types and return types. + +##### Example 1 + +The following code example demonstrates the two ways a delegate can be created using this overload of the method. + +> [!NOTE] +> There are two overloads of the method that specify a but not a first argument; their functionality is the same except that one allows you to specify whether to throw on failure to bind, and the other always throws. This code example uses both overloads. + +The example declares a class `C` with a static method `M2` and an instance method `M1`, and two delegate types: `D1` takes an instance of `C` and a string, and `D2` takes a string. + +A second class named `Example` contains the code that creates the delegates. + +- A delegate of type `D1`, representing an open instance method, is created for the instance method `M1`. An instance must be passed when the delegate is invoked. +- A delegate of type `D2`, representing an open static method, is created for the static method `M2`. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/openClosedOver.vb" id="Snippet1"::: + +##### Example 2 + +The following code example demonstrates compatibility of parameter types and return types. + +The code example defines a base class named `Base` and a class named `Derived` that derives from `Base`. The derived class has a `static` (`Shared` in Visual Basic) method named `MyMethod` with one parameter of type `Base` and a return type of `Derived`. The code example also defines a delegate named `Example` that has one parameter of type `Derived` and a return type of `Base`. + +The code example demonstrates that the delegate named `Example` can be used to represent the method `MyMethod`. The method can be bound to the delegate because: + +- The parameter type of the delegate (`Derived`) is more restrictive than the parameter type of `MyMethod` (`Base`), so that it is always safe to pass the argument of the delegate to `MyMethod`. +- The return type of `MyMethod` (`Derived`) is more restrictive than the parameter type of the delegate (`Base`), so that it is always safe to cast the return type of the method to the return type of the delegate. + +The code example produces no output. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/source1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/source.vb" id="Snippet1"::: + +### and methods + +The functionality of these two overloads is the same except that one allows you to specify whether to throw on failure to bind, and the other always throws. + +The delegate type and the method must have compatible return types. That is, the return type of `method` must be assignable to the return type of `type`. + +`firstArgument`, the second parameter to these overloads, is the first argument of the method the delegate represents. If `firstArgument` is supplied, it is passed to `method` every time the delegate is invoked; `firstArgument` is said to be bound to the delegate, and the delegate is said to be closed over its first argument. If `method` is `static` (`Shared` in Visual Basic), the argument list supplied when invoking the delegate includes all parameters except the first; if `method` is an instance method, then `firstArgument` is passed to the hidden instance parameter (represented by `this` in C#, or by `Me` in Visual Basic). + +If `firstArgument` is supplied, the first parameter of `method` must be a reference type, and `firstArgument` must be compatible with that type. + +> [!IMPORTANT] +> If `method` is `static` (`Shared` in Visual Basic) and its first parameter is of type or , then `firstArgument` can be a value type. In this case `firstArgument` is automatically boxed. Automatic boxing does not occur for any other arguments, as it would in a C# or Visual Basic function call. + +If `firstArgument` is a null reference and `method` is an instance method, the result depends on the signatures of the delegate type `type` and of `method`: + +- If the signature of `type` explicitly includes the hidden first parameter of `method`, the delegate is said to represent an open instance method. When the delegate is invoked, the first argument in the argument list is passed to the hidden instance parameter of `method`. +- If the signatures of `method` and `type` match (that is, all parameter types are compatible), then the delegate is said to be closed over a null reference. Invoking the delegate is like calling an instance method on a null instance, which is not a particularly useful thing to do. + +If `firstArgument` is a null reference and `method` is static, the result depends on the signatures of the delegate type `type` and of `method`: + +- If the signature of `method` and `type` match (that is, all parameter types are compatible), the delegate is said to represent an open static method. This is the most common case for static methods. In this case, you can get slightly better performance by using the method overload. +- If the signature of `type` begins with the second parameter of `method` and the rest of the parameter types are compatible, then the delegate is said to be closed over a null reference. When the delegate is invoked, a null reference is passed to the first parameter of `method`. + +#### Example + +The following code example shows all the methods a single delegate type can represent: closed over an instance method, open over an instance method, open over a static method, and closed over a static method. + +The code example defines two classes, `C` and `F`, and a delegate type `D` with one argument of type `C`. The classes have matching static and instance methods `M1`, `M3`, and `M4`, and class `C` also has an instance method `M2` that has no arguments. + +A third class named `Example` contains the code that creates the delegates. + +- Delegates are created for instance method `M1` of type `C` and type `F`; each is closed over an instance of the respective type. Method `M1` of type `C` displays the `ID` properties of the bound instance and of the argument. +- A delegate is created for method `M2` of type `C`. This is an open instance delegate, in which the argument of the delegate represents the hidden first argument on the instance method. The method has no other arguments. It is called as if it were a static method. +- Delegates are created for static method `M3` of type `C` and type `F`; these are open static delegates. +- Finally, delegates are created for static method `M4` of type `C` and type `F`; each method has the declaring type as its first argument, and an instance of the type is supplied, so the delegates are closed over their first arguments. Method `M4` of type `C` displays the `ID` properties of the bound instance and of the argument. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/source.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/source.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/source1.vb" id="Snippet1"::: + +### Compatible parameter types and return type + +The parameter types and return type of a delegate created using this method overload must be compatible with the parameter types and return type of the method the delegate represents; the types do not have to match exactly. + +A parameter of a delegate is compatible with the corresponding parameter of a method if the type of the delegate parameter is more restrictive than the type of the method parameter, because this guarantees that an argument passed to the delegate can be passed safely to the method. + +Similarly, the return type of a delegate is compatible with the return type of a method if the return type of the method is more restrictive than the return type of the delegate, because this guarantees that the return value of the method can be cast safely to the return type of the delegate. + +For example, a delegate with a parameter of type and a return type of can represent a method with a parameter of type and a return value of type . + +### Determine the methods a delegate can represent + +Another useful way to think of the flexibility provided by the overload is that any given delegate can represent four different combinations of method signature and method kind (static versus instance). Consider a delegate type `D` with one argument of type `C`. The following describes the methods `D` can represent, ignoring the return type since it must match in all cases: + +- `D` can represent any instance method that has exactly one argument of type `C`, regardless of what type the instance method belongs to. When is called, `firstArgument` is an instance of the type `method` belongs to, and the resulting delegate is said to be closed over that instance. (Trivially, `D` can also be closed over a null reference if `firstArgument` is a null reference.) + +- `D` can represent an instance method of `C` that has no arguments. When is called, `firstArgument` is a null reference. The resulting delegate represents an open instance method, and an instance of `C` must be supplied each time it is invoked. + +- `D` can represent a static method that takes one argument of type `C`, and that method can belong to any type. When is called, `firstArgument` is a null reference. The resulting delegate represents an open static method, and an instance of `C` must be supplied each time it is invoked. + +- `D` can represent a static method that belongs to type `F` and has two arguments, of type `F` and type `C`. When is called, `firstArgument` is an instance of `F`. The resulting delegate represents a static method that is closed over that instance of `F`. Note that in the case where `F` and `C` are the same type, the static method has two arguments of that type. (In this case, `D` is closed over a null reference if `firstArgument` is a null reference.) ]]> @@ -671,8 +780,115 @@ This overload can create delegates for static methods and open instance method d > [!NOTE] > This method overload should be used when the delegate is not closed over its first argument, because it is somewhat faster in that case. -For more information about this API, see [Supplemental API remarks for System.Delegate.CreateDelegate](/dotnet/fundamentals/runtime-libraries/system-delegate-createdelegate). - ]]> +The methods create a delegate of a specified type. + +## method + +This method overload is equivalent to calling the method overload and specifying `true` for `throwOnBindFailure`. + +### Examples + +This section contains two code examples. The first example demonstrates the two kinds of delegates that can be created with this method overload: open over an instance method and open over a static method. + +The second code example demonstrates compatible parameter types and return types. + +#### Example 1 + +The following code example demonstrates the two ways a delegate can be created using this overload of the method. + +> [!NOTE] +> There are two overloads of the method that specify a but not a first argument; their functionality is the same except that one allows you to specify whether to throw on failure to bind, and the other always throws. This code example uses both overloads. + +The example declares a class `C` with a static method `M2` and an instance method `M1`, and two delegate types: `D1` takes an instance of `C` and a string, and `D2` takes a string. + +A second class named `Example` contains the code that creates the delegates. + +- A delegate of type `D1`, representing an open instance method, is created for the instance method `M1`. An instance must be passed when the delegate is invoked. +- A delegate of type `D2`, representing an open static method, is created for the static method `M2`. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/openClosedOver.vb" id="Snippet1"::: + +#### Example 2 + +The following code example demonstrates compatibility of parameter types and return types. + +The code example defines a base class named `Base` and a class named `Derived` that derives from `Base`. The derived class has a `static` (`Shared` in Visual Basic) method named `MyMethod` with one parameter of type `Base` and a return type of `Derived`. The code example also defines a delegate named `Example` that has one parameter of type `Derived` and a return type of `Base`. + +The code example demonstrates that the delegate named `Example` can be used to represent the method `MyMethod`. The method can be bound to the delegate because: + +- The parameter type of the delegate (`Derived`) is more restrictive than the parameter type of `MyMethod` (`Base`), so that it is always safe to pass the argument of the delegate to `MyMethod`. +- The return type of `MyMethod` (`Derived`) is more restrictive than the parameter type of the delegate (`Base`), so that it is always safe to cast the return type of the method to the return type of the delegate. + +The code example produces no output. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/source1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/source.vb" id="Snippet1"::: + +## and methods + +The functionality of these two overloads is the same except that one allows you to specify whether to throw on failure to bind, and the other always throws. + +The delegate type and the method must have compatible return types. That is, the return type of `method` must be assignable to the return type of `type`. + +`firstArgument`, the second parameter to these overloads, is the first argument of the method the delegate represents. If `firstArgument` is supplied, it is passed to `method` every time the delegate is invoked; `firstArgument` is said to be bound to the delegate, and the delegate is said to be closed over its first argument. If `method` is `static` (`Shared` in Visual Basic), the argument list supplied when invoking the delegate includes all parameters except the first; if `method` is an instance method, then `firstArgument` is passed to the hidden instance parameter (represented by `this` in C#, or by `Me` in Visual Basic). + +If `firstArgument` is supplied, the first parameter of `method` must be a reference type, and `firstArgument` must be compatible with that type. + +> [!IMPORTANT] +> If `method` is `static` (`Shared` in Visual Basic) and its first parameter is of type or , then `firstArgument` can be a value type. In this case `firstArgument` is automatically boxed. Automatic boxing does not occur for any other arguments, as it would in a C# or Visual Basic function call. + +If `firstArgument` is a null reference and `method` is an instance method, the result depends on the signatures of the delegate type `type` and of `method`: + +- If the signature of `type` explicitly includes the hidden first parameter of `method`, the delegate is said to represent an open instance method. When the delegate is invoked, the first argument in the argument list is passed to the hidden instance parameter of `method`. +- If the signatures of `method` and `type` match (that is, all parameter types are compatible), then the delegate is said to be closed over a null reference. Invoking the delegate is like calling an instance method on a null instance, which is not a particularly useful thing to do. + +If `firstArgument` is a null reference and `method` is static, the result depends on the signatures of the delegate type `type` and of `method`: + +- If the signature of `method` and `type` match (that is, all parameter types are compatible), the delegate is said to represent an open static method. This is the most common case for static methods. In this case, you can get slightly better performance by using the method overload. +- If the signature of `type` begins with the second parameter of `method` and the rest of the parameter types are compatible, then the delegate is said to be closed over a null reference. When the delegate is invoked, a null reference is passed to the first parameter of `method`. + +### Example + +The following code example shows all the methods a single delegate type can represent: closed over an instance method, open over an instance method, open over a static method, and closed over a static method. + +The code example defines two classes, `C` and `F`, and a delegate type `D` with one argument of type `C`. The classes have matching static and instance methods `M1`, `M3`, and `M4`, and class `C` also has an instance method `M2` that has no arguments. + +A third class named `Example` contains the code that creates the delegates. + +- Delegates are created for instance method `M1` of type `C` and type `F`; each is closed over an instance of the respective type. Method `M1` of type `C` displays the `ID` properties of the bound instance and of the argument. +- A delegate is created for method `M2` of type `C`. This is an open instance delegate, in which the argument of the delegate represents the hidden first argument on the instance method. The method has no other arguments. It is called as if it were a static method. +- Delegates are created for static method `M3` of type `C` and type `F`; these are open static delegates. +- Finally, delegates are created for static method `M4` of type `C` and type `F`; each method has the declaring type as its first argument, and an instance of the type is supplied, so the delegates are closed over their first arguments. Method `M4` of type `C` displays the `ID` properties of the bound instance and of the argument. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/source.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/source.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/source1.vb" id="Snippet1"::: + +## Compatible parameter types and return type + +The parameter types and return type of a delegate created using this method overload must be compatible with the parameter types and return type of the method the delegate represents; the types do not have to match exactly. + +A parameter of a delegate is compatible with the corresponding parameter of a method if the type of the delegate parameter is more restrictive than the type of the method parameter, because this guarantees that an argument passed to the delegate can be passed safely to the method. + +Similarly, the return type of a delegate is compatible with the return type of a method if the return type of the method is more restrictive than the return type of the delegate, because this guarantees that the return value of the method can be cast safely to the return type of the delegate. + +For example, a delegate with a parameter of type and a return type of can represent a method with a parameter of type and a return value of type . + +## Determine the methods a delegate can represent + +Another useful way to think of the flexibility provided by the overload is that any given delegate can represent four different combinations of method signature and method kind (static versus instance). Consider a delegate type `D` with one argument of type `C`. The following describes the methods `D` can represent, ignoring the return type since it must match in all cases: + +- `D` can represent any instance method that has exactly one argument of type `C`, regardless of what type the instance method belongs to. When is called, `firstArgument` is an instance of the type `method` belongs to, and the resulting delegate is said to be closed over that instance. (Trivially, `D` can also be closed over a null reference if `firstArgument` is a null reference.) + +- `D` can represent an instance method of `C` that has no arguments. When is called, `firstArgument` is a null reference. The resulting delegate represents an open instance method, and an instance of `C` must be supplied each time it is invoked. + +- `D` can represent a static method that takes one argument of type `C`, and that method can belong to any type. When is called, `firstArgument` is a null reference. The resulting delegate represents an open static method, and an instance of `C` must be supplied each time it is invoked. + +- `D` can represent a static method that belongs to type `F` and has two arguments, of type `F` and type `C`. When is called, `firstArgument` is an instance of `F`. The resulting delegate represents a static method that is closed over that instance of `F`. Note that in the case where `F` and `C` are the same type, the static method has two arguments of that type. (In this case, `D` is closed over a null reference if `firstArgument` is a null reference.) +]]> is . @@ -766,9 +982,115 @@ Calling this method overload is equivalent to calling the [!NOTE] > If you don't supply a first argument, use the method overload for better performance. -For more information about this API, see [Supplemental API remarks for System.Delegate.CreateDelegate](/dotnet/fundamentals/runtime-libraries/system-delegate-createdelegate). +The methods create a delegate of a specified type. - ]]> +## method + +This method overload is equivalent to calling the method overload and specifying `true` for `throwOnBindFailure`. + +### Examples + +This section contains two code examples. The first example demonstrates the two kinds of delegates that can be created with this method overload: open over an instance method and open over a static method. + +The second code example demonstrates compatible parameter types and return types. + +#### Example 1 + +The following code example demonstrates the two ways a delegate can be created using this overload of the method. + +> [!NOTE] +> There are two overloads of the method that specify a but not a first argument; their functionality is the same except that one allows you to specify whether to throw on failure to bind, and the other always throws. This code example uses both overloads. + +The example declares a class `C` with a static method `M2` and an instance method `M1`, and two delegate types: `D1` takes an instance of `C` and a string, and `D2` takes a string. + +A second class named `Example` contains the code that creates the delegates. + +- A delegate of type `D1`, representing an open instance method, is created for the instance method `M1`. An instance must be passed when the delegate is invoked. +- A delegate of type `D2`, representing an open static method, is created for the static method `M2`. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/openClosedOver.vb" id="Snippet1"::: + +#### Example 2 + +The following code example demonstrates compatibility of parameter types and return types. + +The code example defines a base class named `Base` and a class named `Derived` that derives from `Base`. The derived class has a `static` (`Shared` in Visual Basic) method named `MyMethod` with one parameter of type `Base` and a return type of `Derived`. The code example also defines a delegate named `Example` that has one parameter of type `Derived` and a return type of `Base`. + +The code example demonstrates that the delegate named `Example` can be used to represent the method `MyMethod`. The method can be bound to the delegate because: + +- The parameter type of the delegate (`Derived`) is more restrictive than the parameter type of `MyMethod` (`Base`), so that it is always safe to pass the argument of the delegate to `MyMethod`. +- The return type of `MyMethod` (`Derived`) is more restrictive than the parameter type of the delegate (`Base`), so that it is always safe to cast the return type of the method to the return type of the delegate. + +The code example produces no output. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/source1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/source.vb" id="Snippet1"::: + +## and methods + +The functionality of these two overloads is the same except that one allows you to specify whether to throw on failure to bind, and the other always throws. + +The delegate type and the method must have compatible return types. That is, the return type of `method` must be assignable to the return type of `type`. + +`firstArgument`, the second parameter to these overloads, is the first argument of the method the delegate represents. If `firstArgument` is supplied, it is passed to `method` every time the delegate is invoked; `firstArgument` is said to be bound to the delegate, and the delegate is said to be closed over its first argument. If `method` is `static` (`Shared` in Visual Basic), the argument list supplied when invoking the delegate includes all parameters except the first; if `method` is an instance method, then `firstArgument` is passed to the hidden instance parameter (represented by `this` in C#, or by `Me` in Visual Basic). + +If `firstArgument` is supplied, the first parameter of `method` must be a reference type, and `firstArgument` must be compatible with that type. + +> [!IMPORTANT] +> If `method` is `static` (`Shared` in Visual Basic) and its first parameter is of type or , then `firstArgument` can be a value type. In this case `firstArgument` is automatically boxed. Automatic boxing does not occur for any other arguments, as it would in a C# or Visual Basic function call. + +If `firstArgument` is a null reference and `method` is an instance method, the result depends on the signatures of the delegate type `type` and of `method`: + +- If the signature of `type` explicitly includes the hidden first parameter of `method`, the delegate is said to represent an open instance method. When the delegate is invoked, the first argument in the argument list is passed to the hidden instance parameter of `method`. +- If the signatures of `method` and `type` match (that is, all parameter types are compatible), then the delegate is said to be closed over a null reference. Invoking the delegate is like calling an instance method on a null instance, which is not a particularly useful thing to do. + +If `firstArgument` is a null reference and `method` is static, the result depends on the signatures of the delegate type `type` and of `method`: + +- If the signature of `method` and `type` match (that is, all parameter types are compatible), the delegate is said to represent an open static method. This is the most common case for static methods. In this case, you can get slightly better performance by using the method overload. +- If the signature of `type` begins with the second parameter of `method` and the rest of the parameter types are compatible, then the delegate is said to be closed over a null reference. When the delegate is invoked, a null reference is passed to the first parameter of `method`. + +### Example + +The following code example shows all the methods a single delegate type can represent: closed over an instance method, open over an instance method, open over a static method, and closed over a static method. + +The code example defines two classes, `C` and `F`, and a delegate type `D` with one argument of type `C`. The classes have matching static and instance methods `M1`, `M3`, and `M4`, and class `C` also has an instance method `M2` that has no arguments. + +A third class named `Example` contains the code that creates the delegates. + +- Delegates are created for instance method `M1` of type `C` and type `F`; each is closed over an instance of the respective type. Method `M1` of type `C` displays the `ID` properties of the bound instance and of the argument. +- A delegate is created for method `M2` of type `C`. This is an open instance delegate, in which the argument of the delegate represents the hidden first argument on the instance method. The method has no other arguments. It is called as if it were a static method. +- Delegates are created for static method `M3` of type `C` and type `F`; these are open static delegates. +- Finally, delegates are created for static method `M4` of type `C` and type `F`; each method has the declaring type as its first argument, and an instance of the type is supplied, so the delegates are closed over their first arguments. Method `M4` of type `C` displays the `ID` properties of the bound instance and of the argument. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/source.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/source.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/source1.vb" id="Snippet1"::: + +## Compatible parameter types and return type + +The parameter types and return type of a delegate created using this method overload must be compatible with the parameter types and return type of the method the delegate represents; the types do not have to match exactly. + +A parameter of a delegate is compatible with the corresponding parameter of a method if the type of the delegate parameter is more restrictive than the type of the method parameter, because this guarantees that an argument passed to the delegate can be passed safely to the method. + +Similarly, the return type of a delegate is compatible with the return type of a method if the return type of the method is more restrictive than the return type of the delegate, because this guarantees that the return value of the method can be cast safely to the return type of the delegate. + +For example, a delegate with a parameter of type and a return type of can represent a method with a parameter of type and a return value of type . + +## Determine the methods a delegate can represent + +Another useful way to think of the flexibility provided by the overload is that any given delegate can represent four different combinations of method signature and method kind (static versus instance). Consider a delegate type `D` with one argument of type `C`. The following describes the methods `D` can represent, ignoring the return type since it must match in all cases: + +- `D` can represent any instance method that has exactly one argument of type `C`, regardless of what type the instance method belongs to. When is called, `firstArgument` is an instance of the type `method` belongs to, and the resulting delegate is said to be closed over that instance. (Trivially, `D` can also be closed over a null reference if `firstArgument` is a null reference.) + +- `D` can represent an instance method of `C` that has no arguments. When is called, `firstArgument` is a null reference. The resulting delegate represents an open instance method, and an instance of `C` must be supplied each time it is invoked. + +- `D` can represent a static method that takes one argument of type `C`, and that method can belong to any type. When is called, `firstArgument` is a null reference. The resulting delegate represents an open static method, and an instance of `C` must be supplied each time it is invoked. + +- `D` can represent a static method that belongs to type `F` and has two arguments, of type `F` and type `C`. When is called, `firstArgument` is an instance of `F`. The resulting delegate represents a static method that is closed over that instance of `F`. Note that in the case where `F` and `C` are the same type, the static method has two arguments of that type. (In this case, `D` is closed over a null reference if `firstArgument` is a null reference.) +]]> is . @@ -956,7 +1278,46 @@ For more information about this API, see [Supplemental API remarks for System.De > [!NOTE] > This method overload should be used when the delegate is not closed over its first argument, because it is somewhat faster in that case. -For examples, see [Supplemental API remarks for System.Delegate.CreateDelegate](/dotnet/fundamentals/runtime-libraries/system-delegate-createdelegate). +### Examples + +This section contains two code examples. The first example demonstrates the two kinds of delegates that can be created with this method overload: open over an instance method and open over a static method. + +The second code example demonstrates compatible parameter types and return types. + +#### Example 1 + +The following code example demonstrates the two ways a delegate can be created using this overload of the method. + +> [!NOTE] +> There are two overloads of the method that specify a but not a first argument; their functionality is the same except that one allows you to specify whether to throw on failure to bind, and the other always throws. This code example uses both overloads. + +The example declares a class `C` with a static method `M2` and an instance method `M1`, and two delegate types: `D1` takes an instance of `C` and a string, and `D2` takes a string. + +A second class named `Example` contains the code that creates the delegates. + +- A delegate of type `D1`, representing an open instance method, is created for the instance method `M1`. An instance must be passed when the delegate is invoked. +- A delegate of type `D2`, representing an open static method, is created for the static method `M2`. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/openClosedOver.vb" id="Snippet1"::: + +#### Example 2 + +The following code example demonstrates compatibility of parameter types and return types. + +The code example defines a base class named `Base` and a class named `Derived` that derives from `Base`. The derived class has a `static` (`Shared` in Visual Basic) method named `MyMethod` with one parameter of type `Base` and a return type of `Derived`. The code example also defines a delegate named `Example` that has one parameter of type `Derived` and a return type of `Base`. + +The code example demonstrates that the delegate named `Example` can be used to represent the method `MyMethod`. The method can be bound to the delegate because: + +- The parameter type of the delegate (`Derived`) is more restrictive than the parameter type of `MyMethod` (`Base`), so that it is always safe to pass the argument of the delegate to `MyMethod`. +- The return type of `MyMethod` (`Derived`) is more restrictive than the parameter type of the delegate (`Base`), so that it is always safe to cast the return type of the method to the return type of the delegate. + +The code example produces no output. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/source1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/source.vb" id="Snippet1"::: ]]> @@ -1170,7 +1531,41 @@ For examples, see [Supplemental API remarks for System.Delegate.CreateDelegate]( > [!NOTE] > If you do not supply a first argument, use the method overload for better performance. -For more information and examples, see [Supplemental API remarks for System.Delegate.CreateDelegate](/dotnet/fundamentals/runtime-libraries/system-delegate-createdelegate). +The delegate type and the method must have compatible return types. That is, the return type of `method` must be assignable to the return type of `type`. + +`firstArgument`, the second parameter to these overloads, is the first argument of the method the delegate represents. If `firstArgument` is supplied, it is passed to `method` every time the delegate is invoked; `firstArgument` is said to be bound to the delegate, and the delegate is said to be closed over its first argument. If `method` is `static` (`Shared` in Visual Basic), the argument list supplied when invoking the delegate includes all parameters except the first; if `method` is an instance method, then `firstArgument` is passed to the hidden instance parameter (represented by `this` in C#, or by `Me` in Visual Basic). + +If `firstArgument` is supplied, the first parameter of `method` must be a reference type, and `firstArgument` must be compatible with that type. + +> [!IMPORTANT] +> If `method` is `static` (`Shared` in Visual Basic) and its first parameter is of type or , then `firstArgument` can be a value type. In this case `firstArgument` is automatically boxed. Automatic boxing does not occur for any other arguments, as it would in a C# or Visual Basic function call. + +If `firstArgument` is a null reference and `method` is an instance method, the result depends on the signatures of the delegate type `type` and of `method`: + +- If the signature of `type` explicitly includes the hidden first parameter of `method`, the delegate is said to represent an open instance method. When the delegate is invoked, the first argument in the argument list is passed to the hidden instance parameter of `method`. +- If the signatures of `method` and `type` match (that is, all parameter types are compatible), then the delegate is said to be closed over a null reference. Invoking the delegate is like calling an instance method on a null instance, which is not a particularly useful thing to do. + +If `firstArgument` is a null reference and `method` is static, the result depends on the signatures of the delegate type `type` and of `method`: + +- If the signature of `method` and `type` match (that is, all parameter types are compatible), the delegate is said to represent an open static method. This is the most common case for static methods. In this case, you can get slightly better performance by using the method overload. +- If the signature of `type` begins with the second parameter of `method` and the rest of the parameter types are compatible, then the delegate is said to be closed over a null reference. When the delegate is invoked, a null reference is passed to the first parameter of `method`. + +### Example + +The following code example shows all the methods a single delegate type can represent: closed over an instance method, open over an instance method, open over a static method, and closed over a static method. + +The code example defines two classes, `C` and `F`, and a delegate type `D` with one argument of type `C`. The classes have matching static and instance methods `M1`, `M3`, and `M4`, and class `C` also has an instance method `M2` that has no arguments. + +A third class named `Example` contains the code that creates the delegates. + +- Delegates are created for instance method `M1` of type `C` and type `F`; each is closed over an instance of the respective type. Method `M1` of type `C` displays the `ID` properties of the bound instance and of the argument. +- A delegate is created for method `M2` of type `C`. This is an open instance delegate, in which the argument of the delegate represents the hidden first argument on the instance method. The method has no other arguments. It is called as if it were a static method. +- Delegates are created for static method `M3` of type `C` and type `F`; these are open static delegates. +- Finally, delegates are created for static method `M4` of type `C` and type `F`; each method has the declaring type as its first argument, and an instance of the type is supplied, so the delegates are closed over their first arguments. Method `M4` of type `C` displays the `ID` properties of the bound instance and of the argument. + +:::code language="csharp" source="~/snippets/csharp/System/Delegate/CreateDelegate/source.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Delegate/CreateDelegate/source.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Delegate/CreateDelegate/source1.vb" id="Snippet1"::: ]]> diff --git a/xml/System/Double.xml b/xml/System/Double.xml index 91a33065741..5cb76d6d07d 100644 --- a/xml/System/Double.xml +++ b/xml/System/Double.xml @@ -289,7 +289,203 @@ Represents a double-precision floating-point number. - For more information about this API, see Supplemental API remarks for Double. + + value type represents a double-precision 64-bit number with values ranging from negative 1.79769313486232e308 to positive 1.79769313486232e308, as well as positive or negative zero, , , and not a number (). It's intended to represent values that are extremely large (such as distances between planets or galaxies) or extremely small (such as the molecular mass of a substance in kilograms) and that often are imprecise (such as the distance from earth to another solar system). The type complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic. + +## Floating-point representation and precision + +The data type stores double-precision floating-point values in a 64-bit binary format, as shown in the following table: + +| Part | Bits | +|-----------------------------------|-------| +| Significand or mantissa | 0-51 | +| Exponent | 52-62 | +| Sign (0 = Positive, 1 = Negative) | 63 | + +Just as decimal fractions are unable to precisely represent some fractional values (such as 1/3 or ), binary fractions are unable to represent some fractional values. For example, 1/10, which is represented precisely by .1 as a decimal fraction, is represented by .001100110011 as a binary fraction, with the pattern "0011" repeating to infinity. In this case, the floating-point value provides an imprecise representation of the number that it represents. Performing additional mathematical operations on the original floating-point value often tends to increase its lack of precision. For example, if you compare the result of multiplying .1 by 10 and adding .1 to .1 nine times, you see that addition, because it has involved eight more operations, has produced the less precise result. (Prior to .NET 10, this disparity is apparent only if you display the two values by using the "R" [standard numeric format string](/dotnet/standard/base-types/standard-numeric-format-strings), which displays up to all 17 digits of precision supported by the type.) + +:::code language="csharp" source="~/snippets/csharp/System/Double/Overview/representation1.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/representation1.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/representation1.vb" id="Snippet3"::: + +Because some numbers can't be represented exactly as fractional binary values, floating-point numbers can only approximate real numbers. + +All floating-point numbers also have a limited number of significant digits, which also determines how accurately a floating-point value approximates a real number. A value has up to 15 decimal digits of precision, although a maximum of 17 digits is maintained internally. This means that some floating-point operations might lack the precision to change a floating point value. The following example provides an illustration. It defines a very large floating-point value, and then adds the product of and one quadrillion to it. The product, however, is too small to modify the original floating-point value. Its least significant digit is thousandths, whereas the most significant digit in the product is 10-309. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Overview/representation2.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/representation2.fs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/representation2.vb" id="Snippet4"::: + +The limited precision of a floating-point number has several consequences: + +- Two floating-point numbers that appear equal for a particular precision might not compare equal, because their least significant digits are different. In the following example, a series of numbers are added together, and their total is compared with their expected total. + + :::code language="csharp" source="~/snippets/csharp/System/Double/Overview/precisionlist3.cs" id="Snippet6"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/precisionlist3.fs" id="Snippet6"::: + :::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/precisionlist3.vb" id="Snippet6"::: + + The two values are unequal because of a loss of precision during the addition operations. In this case, the issue can be resolved by calling the method to round the values to the desired precision before performing the comparison. + +- A mathematical or comparison operation that uses a floating-point number might not yield the same result if a decimal number is used, because the binary floating-point number might not equal the decimal number. A previous example illustrated this by displaying the result of multiplying .1 by 10 and adding .1 times. + + When accuracy in numeric operations with fractional values is important, you can use the type rather than the type. When accuracy in numeric operations with integral values beyond the range of the types is important, use the type. + +- values have less precision than values. A value that's converted to a seemingly equivalent often does not equal the value because of differences in precision. In the following example, the result of identical division operations is assigned to a and a value. After the value is cast to a , a comparison of the two values shows that they are unequal. + + :::code language="csharp" source="~/snippets/csharp/System/Double/Overview/precisionlist1.cs" id="Snippet5"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/precisionlist1.fs" id="Snippet5"::: + :::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/precisionlist1.vb" id="Snippet5"::: + + To avoid this problem, use either the in place of the data type, or use the method so that both values have the same precision. + +In addition, the result of arithmetic and assignment operations with values might differ slightly by platform because of the loss of precision of the type. For example, the result of assigning a literal value might differ in the 32-bit and 64-bit versions of .NET. The following example illustrates this difference when the literal value -4.42330604244772E-305 and a variable whose value is -4.42330604244772E-305 are assigned to a variable. Note that the result of the method in this case does not suffer from a loss of precision. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Overview/precision1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/precision1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/precision1.vb" id="Snippet1"::: + +## Test for equality + +To be considered equal, two values must represent identical values. However, because of differences in precision between values, or because of a loss of precision by one or both values, floating-point values that are expected to be identical often turn out to be unequal because of differences in their least significant digits. As a result, calls to the method to determine whether two values are equal, or calls to the method to determine the relationship between two values, often yield unexpected results. This is evident in the following example, where two apparently equal values turn out to be unequal because the first has 15 digits of precision, while the second has 17. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Overview/comparison1.cs" id="Snippet9"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/comparison1.fs" id="Snippet9"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/comparison1.vb" id="Snippet9"::: + +In cases where a loss of precision is likely to affect the result of a comparison, you can adopt any of the following alternatives to calling the or method: + +- Call the method to ensure that both values have the same precision. The following example modifies a previous example to use this approach so that two fractional values are equivalent. + + :::code language="csharp" source="~/snippets/csharp/System/Double/Overview/comparison3.cs" id="Snippet11"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/comparison3.fs" id="Snippet11"::: + :::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/comparison3.vb" id="Snippet11"::: + + The problem of precision still applies to rounding of midpoint values. For more information, see the method. + +- Test for approximate equality rather than equality. This requires that you define either an absolute amount by which the two values can differ but still be equal, or that you define a relative amount by which the smaller value can diverge from the larger value. + + > [!WARNING] + > is sometimes used as an absolute measure of the distance between two values when testing for equality. However, measures the smallest possible value that can be added to, or subtracted from, a whose value is zero. For most positive and negative values, the value of is too small to be detected. Therefore, except for values that are zero, we do not recommend its use in tests for equality. + + The following example uses the latter approach to define an `IsApproximatelyEqual` method that tests the relative difference between two values. The method divides by `Math.Max(value1, value2)` so the comparison is relative to the larger (by magnitude) of the two values, which places the result in the correct order of magnitude. If `Math.Max` returns zero (which happens when one value is zero and the other is negative), the method falls back to `Math.Min(value1, value2)` to use the non-zero value as the divisor. It also contrasts the result of calls to the `IsApproximatelyEqual` method and the method. + + :::code language="csharp" source="~/snippets/csharp/System/Double/Overview/comparison4.cs" id="Snippet12"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/comparison4.fs" id="Snippet12"::: + :::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/comparison4.vb" id="Snippet12"::: + +## Floating-point values and exceptions + +Unlike operations with integral types, which throw a for division by zero or an for overflow in a [checked context](/dotnet/csharp/language-reference/statements/checked-and-unchecked), operations with floating-point values don't throw exceptions. Instead, in exceptional situations, the result of a floating-point operation is zero, positive infinity, negative infinity, or not a number (NaN): + +- If the result of a floating-point operation is too small for the destination format, the result is zero. This can occur when two very small numbers are multiplied, as the following example shows. + + :::code language="csharp" source="~/snippets/csharp/System/Double/Overview/exceptional1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/exceptional1.fs" id="Snippet1"::: + :::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/exceptional1.vb" id="Snippet1"::: + +- If the magnitude of the result of a floating-point operation exceeds the range of the destination format, the result of the operation is or , as appropriate for the sign of the result. The result of an operation that overflows is , and the result of an operation that overflows is , as the following example shows. + + :::code language="csharp" source="~/snippets/csharp/System/Double/Overview/exceptional2.cs" id="Snippet2"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/exceptional2.fs" id="Snippet2"::: + :::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/exceptional2.vb" id="Snippet2"::: + + also results from a division by zero with a positive dividend, and results from a division by zero with a negative dividend. + +- If a floating-point operation is invalid, the result of the operation is . For example, results from the following operations: + + - Division by zero with a dividend of zero. Note that other cases of division by zero result in either or . + + - Any floating-point operation with an invalid input. For example, calling the method with a negative value returns , as does calling the method with a value that is greater than one or less than negative one. + + - Any operation with an argument whose value is . + +## Type conversions + +The structure does not define any explicit or implicit conversion operators; instead, conversions are implemented by the compiler. + +The conversion of the value of any primitive numeric type to a is a widening conversion and therefore does not require an explicit cast operator or call to a conversion method unless a compiler explicitly requires it. For example, the C# compiler requires a casting operator for conversions from to , while the Visual Basic compiler does not. The following example converts the minimum or maximum value of other primitive numeric types to a . + +:::code language="csharp" source="~/snippets/csharp/System/Double/Overview/convert1.cs" id="Snippet20"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/convert1.fs" id="Snippet20"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/convert1.vb" id="Snippet20"::: + +In addition, the values , , and convert to , , and , respectively. + +Note that the conversion of the value of some numeric types to a value can involve a loss of precision. As the example illustrates, a loss of precision is possible when converting , , and values to values. + +The conversion of a value to a value of any other primitive numeric data type is a narrowing conversion and requires a cast operator (in C#), a conversion method (in Visual Basic), or a call to a method. Values that are outside the range of the target data type, which are defined by the target type's `MinValue` and `MaxValue` properties, behave as shown in the following table. + +|Target type|Result| +|-----------------|------------| +|Any integral type|An exception if the conversion occurs in a checked context.

If the conversion occurs in an unchecked context (the default in C#), the conversion operation succeeds but the value overflows.| +||An exception.| +|| for negative values.

for positive values.| + +In addition, , , and throw an for conversions to integers in a checked context, but these values overflow when converted to integers in an unchecked context. For conversions to , they always throw an . For conversions to , they convert to , , and , respectively. + +A loss of precision might result from converting a value to another numeric type. In the case of converting to any of the integral types, as the output from the example shows, the fractional component is lost when the value is either rounded (as in Visual Basic) or truncated (as in C#). For conversions to and values, the value might not have a precise representation in the target data type. + +The following example converts a number of values to several other numeric types. The conversions occur in a checked context in Visual Basic (the default), in C# (because of the [checked](/dotnet/csharp/language-reference/keywords/checked) keyword), and in F# (because of the [Checked](https://fsharp.github.io/fsharp-core-docs/reference/fsharp-core-operators-checked.html) module). The output from the example shows the result for conversions in both a checked an unchecked context. You can perform conversions in an unchecked context in Visual Basic by compiling with the `/removeintchecks+` compiler switch, in C# by commenting out the `checked` statement, and in F# by commenting out the `open Checked` statement. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Overview/convert2.cs" id="Snippet21"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/convert2.fs" id="Snippet21"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/convert2.vb" id="Snippet21"::: + +For more information on the conversion of numeric types, see [Type Conversion in .NET](/dotnet/standard/base-types/type-conversion) and [Type Conversion Tables](/dotnet/standard/base-types/conversion-tables). + +## Floating-point functionality + +The structure and related types provide methods to perform operations in the following areas: + +- **Comparison of values**. You can call the method to determine whether two values are equal, or the method to determine the relationship between two values. + + The structure also supports a complete set of comparison operators. For example, you can test for equality or inequality, or determine whether one value is greater than or equal to another. If one of the operands is a numeric type other than a , it is converted to a before performing the comparison. + + > [!WARNING] + > Because of differences in precision, two values that you expect to be equal might turn out to be unequal, which affects the result of the comparison. For information about comparing two values, see the [Test for equality](#test-for-equality) section. + + You can also call the , , , and methods to test for these special values. + +- **Mathematical operations**. Common arithmetic operations, such as addition, subtraction, multiplication, and division, are implemented by language compilers and Common Intermediate Language (CIL) instructions, rather than by methods. If one of the operands in a mathematical operation is a numeric type other than a , it's converted to a before performing the operation. The result of the operation is also a value. + + Other mathematical operations can be performed by calling `static` (`Shared` in Visual Basic) methods in the class. It includes additional methods commonly used for arithmetic (such as , , and ), geometry (such as and ), and calculus (such as ). + + You can also manipulate the individual bits in a value. The method preserves a value's bit pattern in a 64-bit integer. The method returns its bit pattern in a byte array. + +- **Rounding**. Rounding is often used as a technique for reducing the impact of differences between values caused by problems of floating-point representation and precision. You can round a value by calling the method. + +- **Formatting**. You can convert a value to its string representation by calling the method or by using the composite formatting feature. For information about how format strings control the string representation of floating-point values, see [Standard Numeric Format Strings](/dotnet/standard/base-types/standard-numeric-format-strings) and [Custom Numeric Format Strings](/dotnet/standard/base-types/custom-numeric-format-strings). + +- **Parsing strings**. You can convert the string representation of a floating-point value to a value by calling either the or method. If the parse operation fails, the method throws an exception, whereas the method returns `false`. + +- **Type conversion**. The structure provides an explicit interface implementation for the interface, which supports conversion between any two standard .NET data types. Language compilers also support the implicit conversion of values of all other standard numeric types to values. Conversion of a value of any standard numeric type to a is a widening conversion and does not require the user of a casting operator or conversion method, + + However, conversion of and values can involve a loss of precision. The following table lists the differences in precision for each of these types: + + | Type | Maximum precision | Internal precision | + |----------------------|-------------------|--------------------| + | | 15 | 17 | + | | 19 decimal digits | 19 decimal digits | + | | 7 decimal digits | 9 decimal digits | + + The problem of precision most frequently affects values that are converted to values. In the following example, two values produced by identical division operations are unequal because one of the values is a single-precision floating point value converted to a . + + :::code language="csharp" source="~/snippets/csharp/System/Double/Overview/representation1.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/representation1.fs" id="Snippet3"::: + :::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/representation1.vb" id="Snippet3"::: + +## Examples + +The following code example illustrates the use of : + +:::code language="csharp" source="~/snippets/csharp/System/Double/Overview/source.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Overview/source.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Overview/source.vb" id="Snippet1"::: + + ]]>
+
All members of this type are thread safe. Members that appear to modify instance state actually return a new instance initialized with the new value. As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety. @@ -1095,7 +1291,47 @@ This computes `arctan(x) / π` in the interval `[-0.5, +0.5]`. This instance is greater than , or this instance is a number and is not a number (). - For more information about this API, see Double.CompareTo. + + method + +Values must be identical to be considered equal. Particularly when floating-point values depend on multiple mathematical operations, it is common for them to lose precision and for their values to be nearly identical except for their least significant digits. Because of this, the return value of the method at times may seem surprising. For example, multiplication by a particular value followed by division by the same value should produce the original value. In the following example, however, the computed value turns out to be greater than the original value. Showing all significant digits of the two values by using the "R" [standard numeric format string](/dotnet/standard/base-types/standard-numeric-format-strings) indicates that the computed value differs from the original value in its least significant digits. For information on handling such comparisons, see the Remarks section of the method. + +:::code language="csharp" source="~/snippets/csharp/System/Double/CompareTo/compareto2.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/CompareTo/compareto2.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/CompareTo/compareto2.vb" id="Snippet1"::: + +This method implements the interface and performs slightly better than the method because it does not have to convert the `value` parameter to an object. + +Note that, although an object whose value is is not considered equal to another object whose value is (even itself), the interface requires that `A.CompareTo(A)` return zero. + +## method + +The `value` parameter must be `null` or an instance of `Double`; otherwise, an exception is thrown. Any instance of , regardless of its value, is considered greater than `null`. + +Values must be identical to be considered equal. Particularly when floating-point values depend on multiple mathematical operations, it is common for them to lose precision and for their values to be nearly identical except for their least significant digits. Because of this, the return value of the method at times may seem surprising. For example, multiplication by a particular value followed by division by the same value should produce the original value. In the following example, however, the computed value turns out to be greater than the original value. Showing all significant digits of the two values by using the "R" [standard numeric format string](/dotnet/standard/base-types/standard-numeric-format-strings) indicates that the computed value differs from the original value in its least significant digits. For information on handling such comparisons, see the Remarks section of the method. + +:::code language="csharp" source="~/snippets/csharp/System/Double/CompareTo/compareto3.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/CompareTo/compareto3.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/CompareTo/compareto3.vb" id="Snippet2"::: + +This method is implemented to support the interface. Note that, although a is not considered to be equal to another (even itself), the interface requires that `A.CompareTo(A)` return zero. + +## Widening conversions + +Depending on your programming language, it might be possible to code a method where the parameter type has fewer bits (is narrower) than the instance type. This is possible because some programming languages perform an implicit widening conversion that represents the parameter as a type with as many bits as the instance. + +For example, suppose the instance type is and the parameter type is . The Microsoft C# compiler generates instructions to represent the value of the parameter as a object, then generates a method that compares the values of the instance and the widened representation of the parameter. + +Consult your programming language's documentation to determine if its compiler performs implicit widening conversions of numeric types. For more information, see the [Type Conversion Tables](/dotnet/standard/base-types/conversion-tables) topic. + +## Precision in comparisons + +The precision of floating-point numbers beyond the documented precision is specific to the implementation and version of .NET. Consequently, a comparison of two particular numbers might change between versions of .NET because the precision of the numbers' internal representation might change. + + ]]> + method for several value and reference types. @@ -1168,7 +1404,47 @@ The following code example demonstrates generic and nongeneric versions of the < This instance is equal to , or this instance and are both , , or A positive integer This instance is greater than , OR this instance is a number and is not a number (), OR is . - For more information about this API, see Double.CompareTo. + + method + +Values must be identical to be considered equal. Particularly when floating-point values depend on multiple mathematical operations, it is common for them to lose precision and for their values to be nearly identical except for their least significant digits. Because of this, the return value of the method at times may seem surprising. For example, multiplication by a particular value followed by division by the same value should produce the original value. In the following example, however, the computed value turns out to be greater than the original value. Showing all significant digits of the two values by using the "R" [standard numeric format string](/dotnet/standard/base-types/standard-numeric-format-strings) indicates that the computed value differs from the original value in its least significant digits. For information on handling such comparisons, see the Remarks section of the method. + +:::code language="csharp" source="~/snippets/csharp/System/Double/CompareTo/compareto2.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/CompareTo/compareto2.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/CompareTo/compareto2.vb" id="Snippet1"::: + +This method implements the interface and performs slightly better than the method because it does not have to convert the `value` parameter to an object. + +Note that, although an object whose value is is not considered equal to another object whose value is (even itself), the interface requires that `A.CompareTo(A)` return zero. + +## method + +The `value` parameter must be `null` or an instance of `Double`; otherwise, an exception is thrown. Any instance of , regardless of its value, is considered greater than `null`. + +Values must be identical to be considered equal. Particularly when floating-point values depend on multiple mathematical operations, it is common for them to lose precision and for their values to be nearly identical except for their least significant digits. Because of this, the return value of the method at times may seem surprising. For example, multiplication by a particular value followed by division by the same value should produce the original value. In the following example, however, the computed value turns out to be greater than the original value. Showing all significant digits of the two values by using the "R" [standard numeric format string](/dotnet/standard/base-types/standard-numeric-format-strings) indicates that the computed value differs from the original value in its least significant digits. For information on handling such comparisons, see the Remarks section of the method. + +:::code language="csharp" source="~/snippets/csharp/System/Double/CompareTo/compareto3.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/CompareTo/compareto3.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/CompareTo/compareto3.vb" id="Snippet2"::: + +This method is implemented to support the interface. Note that, although a is not considered to be equal to another (even itself), the interface requires that `A.CompareTo(A)` return zero. + +## Widening conversions + +Depending on your programming language, it might be possible to code a method where the parameter type has fewer bits (is narrower) than the instance type. This is possible because some programming languages perform an implicit widening conversion that represents the parameter as a type with as many bits as the instance. + +For example, suppose the instance type is and the parameter type is . The Microsoft C# compiler generates instructions to represent the value of the parameter as a object, then generates a method that compares the values of the instance and the widened representation of the parameter. + +Consult your programming language's documentation to determine if its compiler performs implicit widening conversions of numeric types. For more information, see the [Type Conversion Tables](/dotnet/standard/base-types/conversion-tables) topic. + +## Precision in comparisons + +The precision of floating-point numbers beyond the documented precision is specific to the implementation and version of .NET. Consequently, a comparison of two particular numbers might change between versions of .NET because the precision of the numbers' internal representation might change. + + ]]> + 4.94065645841247E-324 Represents the smallest positive value that is greater than zero. This field is constant. - For more information about this API, see Supplemental API remarks for Double.Epsilon. + + property reflects the smallest positive value that is significant in numeric operations or comparisons when the value of the instance is zero. For example, the following code shows that zero and are considered to be unequal values, whereas zero and half the value of are considered to be equal. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Epsilon/epsilon.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Epsilon/epsilon.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Epsilon/epsilon.vb" id="Snippet5"::: + +More precisely, the floating point format consists of a sign, a 52-bit mantissa or significand, and an 11-bit exponent. As the following example shows, zero has an exponent of -1022 and a mantissa of 0. has an exponent of -1022 and a mantissa of 1. This means that is the smallest positive value greater than zero and represents the smallest possible value and the smallest possible increment for a whose exponent is -1022. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Epsilon/epsilon1.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Epsilon/epsilon1.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Epsilon/epsilon1.vb" id="Snippet6"::: + +However, the property is not a general measure of precision of the type; it applies only to instances that have a value of zero or an exponent of -1022. + +> [!NOTE] +> The value of the property is not equivalent to machine epsilon, which represents the upper bound of the relative error due to rounding in floating-point arithmetic. + +The value of this constant is 4.94065645841247e-324. + +Two apparently equivalent floating-point numbers might not compare equal because of differences in their least significant digits. For example, the C# expression, `(double)1/3 == (double)0.33333`, does not compare equal because the division operation on the left side has maximum precision while the constant on the right side is precise only to the specified digits. If you create a custom algorithm that determines whether two floating-point numbers can be considered equal, we do not recommend that you base your algorithm on the value of the constant to establish the acceptable absolute margin of difference for the two values to be considered equal. (Typically, that margin of difference is many times greater than .) For information about comparing two double-precision floating-point values, see and . + +## Platform notes + +On ARM systems, the value of the constant is too small to be detected, so it equates to zero. You can define an alternative epsilon value that equals 2.2250738585072014E-308 instead. + + ]]> + @@ -1767,7 +2072,55 @@ Euler's number is approximately 2.7182818284590452354. Returns a value indicating whether this instance and a specified object represent the same value. if is equal to this instance; otherwise, . - For more information about this API, see Supplemental API remarks for Double.Equals. + + method implements the interface, and performs slightly better than because it doesn't have to convert the `obj` parameter to an object. + +## Widening conversions + +Depending on your programming language, it might be possible to code a method where the parameter type has fewer bits (is narrower) than the instance type. This is possible because some programming languages perform an implicit widening conversion that represents the parameter as a type with as many bits as the instance. + +For example, suppose the instance type is and the parameter type is . The Microsoft C# compiler generates instructions to represent the value of the parameter as a object, then generates a method that compares the values of the instance and the widened representation of the parameter. + +Consult your programming language's documentation to determine if its compiler performs implicit widening conversions of numeric types. For more information, see the [Type Conversion Tables](/dotnet/standard/base-types/conversion-tables) topic. + +## Precision in comparisons + +The method should be used with caution, because two apparently equivalent values can be unequal due to the differing precision of the two values. The following example reports that the value .333333 and the value returned by dividing 1 by 3 are unequal. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Epsilon/Equals_25051.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Epsilon/Equals_25051.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Epsilon/Equals_25051.vb" id="Snippet1"::: + +Rather than comparing for equality, one technique involves defining an acceptable relative margin of difference between two values (such as .001% of one of the values). If the absolute value of the difference between the two values is less than or equal to that margin, the difference is likely to be due to differences in precision and, therefore, the values are likely to be equal. The following example uses this technique to compare .33333 and 1/3, the two values that the previous code example found to be unequal. In this case, the values are equal. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Epsilon/Equals_25051.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Epsilon/Equals_25051.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Epsilon/Equals_25051.vb" id="Snippet2"::: + +> [!NOTE] +> Because defines the minimum expression of a positive value whose range is near zero, the margin of difference between two similar values must be greater than . Typically, it is many times greater than . Because of this, we recommend that you **don't** use when comparing values for equality. + +A second technique involves comparing the difference between two floating-point numbers with some absolute value. If the difference is less than or equal to that absolute value, the numbers are equal. If it's greater, the numbers are not equal. One alternative is to arbitrarily select an absolute value. That's problematic, however, because an acceptable margin of difference depends on the magnitude of the values. A second alternative takes advantage of a design feature of the floating-point format: The difference between the integer representation of two floating-point values indicates the number of possible floating-point values that separates them. For example, the difference between 0.0 and is 1, because is the smallest representable value when working with a whose value is zero. The following example uses this technique to compare .33333 and 1/3, which are the two values that the previous code example with the method found to be unequal. The example uses the method to convert a double-precision floating-point value to its integer representation. The example declares the values as equal if there are no possible floating-point values between their integer representations. + +:::code language="csharp" source="~/snippets/csharp/System/Double/Equals/equalsabs1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Double/Equals/equalsabs1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Double/Equals/equalsabs1.vb" id="Snippet1"::: + +> [!NOTE] +> For some values, you might consider them equal even when there *is* a possible floating-point value between the integer representations. For example, consider the double values `0.39` and `1.69 - 1.3` (which is calculated as `0.3899999999999999`). On a little-endian computer, the integer representations of these values are `4600697235336603894` and `4600697235336603892`, respectively. The difference between the integer values is `2`, meaning there *is* a possible floating-point value between `0.39` and `1.69 - 1.3`. + +### Version differences + +The precision of floating-point numbers beyond the documented precision is specific to the implementation and version of .NET. Consequently, a comparison of two particular numbers might change between versions of .NET because the precision of the numbers' internal representation might change. + +## NaN + +If two values are tested for equality by calling the method, the method returns `true`. However, if two values are tested for equality by using the *equality operator*, the operator returns `false`. When you want to determine whether the value of a is not a number (NaN), an alternative is to call the method. + + ]]> + Compiler overload resolution may account for an apparent difference in the behavior of the two method overloads. If an implicit conversion between the argument and a is defined and the argument is not typed as an , compilers may perform an implicit conversion and call the method. Otherwise, they call the method, which always returns if its argument is not a value. The following example illustrates the difference in behavior between the two method overloads. In the case of all primitive numeric types except for and in C#, the first comparison returns because the compiler automatically performs a widening conversion and calls the method, whereas the second comparison returns because the compiler calls the method. diff --git a/xml/System/Enum.xml b/xml/System/Enum.xml index 1dcee1f00e6..8eb48380a99 100644 --- a/xml/System/Enum.xml +++ b/xml/System/Enum.xml @@ -74,7 +74,194 @@ Provides the base class for enumerations. - For more information about this API, see Supplemental API remarks for Enum. + + is used. is the base class for all enumerations in .NET. Enumeration types are defined by the `enum` keyword in C#, the `Enum`...`End Enum` construct in Visual Basic, and the `type` keyword in F#. + + provides methods for comparing instances of this class, converting the value of an instance to its string representation, converting the string representation of a number to an instance of this class, and creating an instance of a specified enumeration and value. + +You can also treat an enumeration as a bit field. For more information, see the [Non-exclusive members and the Flags attribute](#non-exclusive-members-and-the-flags-attribute) section and . + +## Create an enumeration type + +Programming languages typically provide syntax to declare an enumeration that consists of a set of named constants and their values. The following example illustrates the syntax used by C#, F#, and Visual Basic to define an enumeration. It creates an enumeration named `ArrivalStatus` that has three members: `ArrivalStatus.Early`, `ArrivalStatus.OnTime`, and `ArrivalStatus.Late`. Note that in all cases, the enumeration does not explicitly inherit from ; the inheritance relationship is handled implicitly by the compiler. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/class1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/class1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/class1.vb" id="Snippet1"::: + +> [!WARNING] +> You should never create an enumeration type whose underlying type is non-integral or . Although you can create such an enumeration type by using reflection, method calls that use the resulting type are unreliable and may also throw additional exceptions. + +## Instantiate an enumeration type + +You can instantiate an enumeration type just as you instantiate any other value type: by declaring a variable and assigning one of the enumeration's constants to it. The following example instantiates an `ArrivalStatus` whose value is `ArrivalStatus.OnTime`. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/class1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/class1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/class1.vb" id="Snippet2"::: + +You can also instantiate an enumeration value in the following ways: + +- By using a particular programming language's features to cast (as in C#) or convert (as in Visual Basic) an integer value to an enumeration value. The following example creates an `ArrivalStatus` object whose value is `ArrivalStatus.Early` in this way. + + :::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/class2.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/class2.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/class2.vb" id="Snippet4"::: + +- By calling its implicit parameterless constructor. As the following example shows, in this case the underlying value of the enumeration instance is 0. However, this is not necessarily the value of a valid constant in the enumeration. + + :::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/class2.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/class2.fs" id="Snippet3"::: + :::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/class2.vb" id="Snippet3"::: + +- By calling the or method to parse a string that contains the name of a constant in the enumeration. For more information, see the [Parse enumeration values](#parse-enumeration-values) section. + +- By calling the method to convert an integral value to an enumeration type. For more information, see the [Perform conversions](#perform-conversions) section. + +## Enumeration best practices + +We recommend that you use the following best practices when you define enumeration types: + +- If you have not defined an enumeration member whose value is 0, consider creating a `None` enumerated constant. By default, the memory used for the enumeration is initialized to zero by the common language runtime. Consequently, if you do not define a constant whose value is zero, the enumeration will contain an illegal value when it is created. + +- If there is an obvious default case that your application has to represent, consider using an enumerated constant whose value is zero to represent it. If there is no default case, consider using an enumerated constant whose value is zero to specify the case that is not represented by any of the other enumerated constants. + +- Do not specify enumerated constants that are reserved for future use. + +- When you define a method or property that takes an enumerated constant as a value, consider validating the value. The reason is that you can cast a numeric value to the enumeration type even if that numeric value is not defined in the enumeration. + +Additional best practices for enumeration types whose constants are bit fields are listed in the [Non-exclusive members and the Flags attribute](#non-exclusive-members-and-the-flags-attribute) section. + +## Perform operations with enumerations + +You cannot define new methods when you are creating an enumeration. However, an enumeration type inherits a complete set of static and instance methods from the class. The following sections survey most of these methods, in addition to several other methods that are commonly used when working with enumeration values. + +### Perform conversions + +You can convert between an enumeration member and its underlying type by using a casting (in C# and F#), or conversion (in Visual Basic) operator. In F#, the `enum` function is also used. The following example uses casting or conversion operators to perform conversions both from an integer to an enumeration value and from an enumeration value to an integer. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/class2.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/class2.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/class2.vb" id="Snippet5"::: + +The class also includes a method that converts a value of any integral type to an enumeration value. The following example uses the method to convert an to an `ArrivalStatus` value. Note that, because the returns a value of type , the use of a casting or conversion operator may still be necessary to cast the object to the enumeration type. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/class2.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/class2.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/class2.vb" id="Snippet6"::: + +When converting an integer to an enumeration value, it is possible to assign a value that is not actually a member of the enumeration. To prevent this, you can pass the integer to the method before performing the conversion. The following example uses this method to determine whether the elements in an array of integer values can be converted to `ArrivalStatus` values. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classconversion1.cs" id="Snippet7"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classconversion1.fs" id="Snippet7"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classconversion1.vb" id="Snippet7"::: + +Although the class provides explicit interface implementations of the interface for converting from an enumeration value to an integral type, you should use the methods of the class, such as , to perform these conversions. The following example illustrates how you can use the method along with the method to convert an enumeration value to its underlying type. Note that this example does not require the underlying type of the enumeration to be known at compile time. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classconversion2.cs" id="Snippet8"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classconversion2.fs" id="Snippet8"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classconversion2.vb" id="Snippet8"::: + +### Parse enumeration values + +The and methods allow you to convert the string representation of an enumeration value to that value. The string representation can be either the name or the underlying value of an enumeration constant. Note that the parsing methods will successfully convert string representations of numbers that are not members of a particular enumeration if the strings can be converted to a value of the enumeration's underlying type. To prevent this, the method can be called to ensure that the result of the parsing method is a valid enumeration value. The example illustrates this approach and demonstrates calls to both the and methods. Note that the non-generic parsing method returns an object that you may have to cast (in C# and F#) or convert (in Visual Basic) to the appropriate enumeration type. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classparse1.cs" id="Snippet9"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classparse1.fs" id="Snippet9"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classparse1.vb" id="Snippet9"::: + +### Format enumeration values + +You can convert enumeration values to their string representations by calling the static method, as well as the overloads of the instance method. You can use a format string to control the precise way in which an enumeration value is represented as a string. For more information, see [Enumeration Format Strings](/dotnet/standard/base-types/enumeration-format-strings). The following example uses each of the supported enumeration format strings ("G" or "g", "D" or "d", "X" or "x", and "F" or "f" ) to convert a member of the `ArrivalStatus` enumeration to its string representations. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classformat1.cs" id="Snippet10"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classformat1.fs" id="Snippet10"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classformat1.vb" id="Snippet10"::: + +### Iterate enumeration members + +The type does not implement the or interface, which would enable you to iterate members of a collection by using a `foreach` (in C#), `for..in` (in F#), or `For Each` (in Visual Basic) construct. However, you can enumerate members in either of two ways. + +- You can call the method to retrieve a string array containing the names of the enumeration members. Next, for each element of the string array, you can call the method to convert the string to its equivalent enumeration value. The following example illustrates this approach. + + :::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classiterate.cs" id="Snippet11"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classiterate.fs" id="Snippet11"::: + :::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classiterate.vb" id="Snippet11"::: + +- You can call the method to retrieve an array that contains the underlying values in the enumeration. Next, for each element of the array, you can call the method to convert the integer to its equivalent enumeration value. The following example illustrates this approach. + + :::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classiterate.cs" id="Snippet12"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classiterate.fs" id="Snippet12"::: + :::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classiterate.vb" id="Snippet12"::: + +## Non-exclusive members and the Flags attribute + +One common use of an enumeration is to represent a set of mutually exclusive values. For example, an `ArrivalStatus` instance can have a value of `Early`, `OnTime`, or `Late`. It makes no sense for the value of an `ArrivalStatus` instance to reflect more than one enumeration constant. + +In other cases, however, the value of an enumeration object can include multiple enumeration members, and each member represents a bit field in the enumeration value. The attribute can be used to indicate that the enumeration consists of bit fields. For example, an enumeration named `Pets` might be used to indicate the kinds of pets in a household. It can be defined as follows. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classbitwise1.cs" id="Snippet13"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classbitwise1.fs" id="Snippet13"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classbitwise1.vb" id="Snippet13"::: + +The `Pets` enumeration can then be used as shown in the following example. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classbitwise1.cs" id="Snippet14"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classbitwise1.fs" id="Snippet14"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classbitwise1.vb" id="Snippet14"::: + +The following best practices should be used when defining a bitwise enumeration and applying the attribute. + +- Use the custom attribute for an enumeration only if a bitwise operation (AND, OR, EXCLUSIVE OR) is to be performed on a numeric value. + +- Define enumeration constants in powers of two, that is, 1, 2, 4, 8, and so on. This means the individual flags in combined enumeration constants do not overlap. + +- Consider creating an enumerated constant for commonly used flag combinations. For example, if you have an enumeration used for file I/O operations that contains the enumerated constants `Read = 1` and `Write = 2`, consider creating the enumerated constant `ReadWrite = Read OR Write`, which combines the `Read` and `Write` flags. In addition, the bitwise OR operation used to combine the flags might be considered an advanced concept in some circumstances that should not be required for simple tasks. + +- Use caution if you define a negative number as a flag enumerated constant because many flag positions might be set to 1, which might make your code confusing and encourage coding errors. + +- A convenient way to test whether a flag is set in a numeric value is to call the instance method, as shown in the following example. + + :::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classbitwise1.cs" id="Snippet15"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classbitwise1.fs" id="Snippet15"::: + :::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classbitwise1.vb" id="Snippet15"::: + + It is equivalent to performing a bitwise AND operation between the numeric value and the flag enumerated constant, which sets all bits in the numeric value to zero that do not correspond to the flag, and then testing whether the result of that operation is equal to the flag enumerated constant. This is illustrated in the following example. + + :::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classbitwise1.cs" id="Snippet16"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classbitwise1.fs" id="Snippet16"::: + :::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classbitwise1.vb" id="Snippet16"::: + +- Use `None` as the name of the flag enumerated constant whose value is zero. You cannot use the `None` enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. However, you can perform a logical, not a bitwise, comparison between the numeric value and the `None` enumerated constant to determine whether any bits in the numeric value are set. This is illustrated in the following example. + + :::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/classbitwise1.cs" id="Snippet17"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/classbitwise1.fs" id="Snippet17"::: + :::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/classbitwise1.vb" id="Snippet17"::: + +- Do not define an enumeration value solely to mirror the state of the enumeration itself. For example, do not define an enumerated constant that merely marks the end of the enumeration. If you need to determine the last value of the enumeration, check for that value explicitly. In addition, you can perform a range check for the first and last enumerated constant if all values within the range are valid. + +## Add enumeration methods + +Because enumeration types are defined by language structures, such as `enum` (C#), and `Enum` (Visual Basic), you cannot define custom methods for an enumeration type other than those methods inherited from the class. However, you can use extension methods to add functionality to a particular enumeration type. + +In the following example, the `Grades` enumeration represents the possible letter grades that a student may receive in a class. An extension method named `Passing` is added to the `Grades` type so that each instance of that type now "knows" whether it represents a passing grade or not. The `Extensions` class also contains a static read-write variable that defines the minimum passing grade. The return value of the `Passing` extension method reflects the current value of that variable. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/Extensions.cs" id="Snippet18"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/Extensions.fs" id="Snippet18"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/Extensions.vb" id="Snippet18"::: + +## Examples + +The following example demonstrates using an enumeration to represent named values and another enumeration to represent named bit fields. + +:::code language="csharp" source="~/snippets/csharp/System/Enum/Overview/EnumMain.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Enum/Overview/EnumMain.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Enum/Overview/EnumMain.vb" id="Snippet1"::: + + ]]> + This type is thread safe. diff --git a/xml/System/Environment.xml b/xml/System/Environment.xml index b6e2e87cd0c..7c9ba7c4471 100644 --- a/xml/System/Environment.xml +++ b/xml/System/Environment.xml @@ -882,7 +882,64 @@ In .NET 5 and later versions, for single-file publishing, the first element is t The name of the environment variable. Retrieves the value of an environment variable from the current process. The value of the environment variable specified by , or if the environment variable is not found. - For more information about this API, see Supplemental API remarks for Environment.GetEnvironmentVariable. + + method retrieves the value of an environment variable from the current process. + +Environment variable names are case-sensitive on Unix-like systems but aren't case-sensitive on Windows. + +> [!NOTE] +> In-process environment modifications made by native libraries aren't seen by managed callers. Conversely, such modifications made by managed callers aren't seen by native libraries. + +## method + +The method retrieves an environment variable from the environment block of the current process only. It's equivalent to calling the method with a `target` value of . + +To retrieve all environment variables along with their values, call the method. + +### On Windows systems + +On Windows systems, the environment block of the current process includes: + +- All environment variables that are provided to it by the parent process that created it. For example, a .NET application launched from a console window inherits all of the console window's environment variables. + + If there is no parent process, per-machine and per-user environment variables are used instead. For example, a new console window has all per-machine and per-user environment variables defined at the time it was launched. + +- Any variables added to the process block while the process is running by calling either the method or the method with a `target` value of . These environment variables persist until the .NET application terminates. + +If environment variables are created after the process has started, you can use this method to retrieve only those variables that were created by calling the method or the method with a `target` value of .. + +### On Unix-like systems + +On Unix-like systems, the environment block of the current process includes the following environment variables: + +- All environment variables that are provided to it by the parent process that created it. For .NET applications launched from a shell, this includes all environment variables defined in the shell. + +- Any variables added to the process block while the process is running by calling either the method or the method with a `target` value of . These environment variables persist until the .NET application terminates. + +.NET on Unix-like systems does not support per-machine or per-user environment variables. + +## method + +To retrieve all environment variables along with their values, call the method. + +### On Windows systems + +On Windows, the `target` parameter specifies whether the environment variable is retrieved from the current process or from the Windows operating system registry key for the current user or local machine. All per-user and per-machine environment variables are automatically copied into the environment block of the current process, as are any other environment variables that are available to the parent process that created the .NET process. However, environment variables added only to the environment block of the current process by calling either the method or the method with a `target` value of persist only for the duration of the process. + +### On Unix-like systems + +On Unix-like systems, the `GetEnvironmentVariable(String, EnvironmentVariableTarget)` method supports a `target` value of only. Calls with a `target` value of or are not supported and return `null`. + +Per-process environment variables are: + +- Those inherited from the parent process, typically the shell used to invoke `dotnet.exe` or to launch the .NET application. + +- Those defined by calling either the method or the method with a `target` value of . These environment variables persist only until the `dotnet` process or the .NET application terminates. + + ]]> + method to retrieve the `windir` environment variable, which contains the path of the Windows directory. @@ -960,7 +1017,64 @@ The following example attempts to retrieve the value of an environment variable One of the values. Only is supported on .NET running on Unix-like systems. Retrieves the value of an environment variable from the current process or from the Windows operating system registry key for the current user or local machine. The value of the environment variable specified by the and parameters, or if the environment variable is not found. - For more information about this API, see Supplemental API remarks for Environment.GetEnvironmentVariable. + + method retrieves the value of an environment variable from the current process. + +Environment variable names are case-sensitive on Unix-like systems but aren't case-sensitive on Windows. + +> [!NOTE] +> In-process environment modifications made by native libraries aren't seen by managed callers. Conversely, such modifications made by managed callers aren't seen by native libraries. + +## method + +The method retrieves an environment variable from the environment block of the current process only. It's equivalent to calling the method with a `target` value of . + +To retrieve all environment variables along with their values, call the method. + +### On Windows systems + +On Windows systems, the environment block of the current process includes: + +- All environment variables that are provided to it by the parent process that created it. For example, a .NET application launched from a console window inherits all of the console window's environment variables. + + If there is no parent process, per-machine and per-user environment variables are used instead. For example, a new console window has all per-machine and per-user environment variables defined at the time it was launched. + +- Any variables added to the process block while the process is running by calling either the method or the method with a `target` value of . These environment variables persist until the .NET application terminates. + +If environment variables are created after the process has started, you can use this method to retrieve only those variables that were created by calling the method or the method with a `target` value of .. + +### On Unix-like systems + +On Unix-like systems, the environment block of the current process includes the following environment variables: + +- All environment variables that are provided to it by the parent process that created it. For .NET applications launched from a shell, this includes all environment variables defined in the shell. + +- Any variables added to the process block while the process is running by calling either the method or the method with a `target` value of . These environment variables persist until the .NET application terminates. + +.NET on Unix-like systems does not support per-machine or per-user environment variables. + +## method + +To retrieve all environment variables along with their values, call the method. + +### On Windows systems + +On Windows, the `target` parameter specifies whether the environment variable is retrieved from the current process or from the Windows operating system registry key for the current user or local machine. All per-user and per-machine environment variables are automatically copied into the environment block of the current process, as are any other environment variables that are available to the parent process that created the .NET process. However, environment variables added only to the environment block of the current process by calling either the method or the method with a `target` value of persist only for the duration of the process. + +### On Unix-like systems + +On Unix-like systems, the `GetEnvironmentVariable(String, EnvironmentVariableTarget)` method supports a `target` value of only. Calls with a `target` value of or are not supported and return `null`. + +Per-process environment variables are: + +- Those inherited from the parent process, typically the shell used to invoke `dotnet.exe` or to launch the .NET application. + +- Those defined by calling either the method or the method with a `target` value of . These environment variables persist only until the `dotnet` process or the .NET application terminates. + + ]]> + , , and targets, checks whether the operating system registry contains the user and machine environment variables, then deletes the environment variables. Because .NET on Unix-like systems does not support per-user and per-machine environment variables, only and with a value of successfully store an environment variable to the process environment block. diff --git a/xml/System/Exception.xml b/xml/System/Exception.xml index 61b910aa357..a5358292e6f 100644 --- a/xml/System/Exception.xml +++ b/xml/System/Exception.xml @@ -64,7 +64,229 @@ Represents errors that occur during application execution. - For more information about this API, see Supplemental API remarks for Exception. + + class is the base class for all exceptions. When an error occurs, either the system or the currently executing application reports it by throwing an exception that contains information about the error. After an exception is thrown, it is handled by the application or by the default exception handler. + +## Errors and exceptions + +Runtime errors can occur for a variety of reasons. However, not all errors should be handled as exceptions in your code. Here are some categories of errors that can occur at runtime and the appropriate ways to respond to them. + +- **Usage errors.** A usage error represents an error in program logic that can result in an exception. However, the error should be addressed not through exception handling but by modifying the faulty code. For example, the override of the method in the following example assumes that the `obj` argument must always be non-null. + + :::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/usageerrors1.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/usageerrors1.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/usageerrors1.vb" id="Snippet4"::: + + The exception that results when `obj` is `null` can be eliminated by modifying the source code to explicitly test for null before calling the override and then re-compiling. The following example contains the corrected source code that handles a `null` argument. + + :::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/usageerrors2.cs" id="Snippet5"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/usageerrors2.fs" id="Snippet5"::: + :::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/usageerrors2.vb" id="Snippet5"::: + + Instead of using exception handling for usage errors, you can use the method to identify usage errors in debug builds, and the method to identify usage errors in both debug and release builds. For more information, see [Assertions in Managed Code](/visualstudio/debugger/assertions-in-managed-code). + +- **Program errors.** A program error is a runtime error that cannot necessarily be avoided by writing bug-free code. + + In some cases, a program error may reflect an expected or routine error condition. In this case, you may want to avoid using exception handling to deal with the program error and instead retry the operation. For example, if the user is expected to input a date in a particular format, you can parse the date string by calling the method, which returns a value that indicates whether the parse operation succeeded, instead of using the method, which throws a exception if the date string cannot be converted to a value. Similarly, if a user tries to open a file that does not exist, you can first call the method to check whether the file exists and, if it does not, prompt the user whether they want to create it. + + In other cases, a program error reflects an unexpected error condition that can be handled in your code. For example, even if you've checked to ensure that a file exists, it may be deleted before you can open it, or it may be corrupted. In that case, trying to open the file by instantiating a object or calling the method may throw a exception. In these cases, you should use exception handling to recover from the error. + +- **System failures.** A system failure is a runtime error that cannot be handled programmatically in a meaningful way. For example, any method can throw an exception if the common language runtime is unable to allocate additional memory. Ordinarily, system failures are not handled by using exception handling. Instead, you may be able to use an event such as and call the method to log exception information and notify the user of the failure before the application terminates. + +## Try/catch blocks + +The common language runtime provides an exception handling model that is based on the representation of exceptions as objects, and the separation of program code and exception handling code into `try` blocks and `catch` blocks. There can be one or more `catch` blocks, each designed to handle a particular type of exception, or one block designed to catch a more specific exception than another block. + +If an application handles exceptions that occur during the execution of a block of application code, the code must be placed within a `try` statement and is called a `try` block. Application code that handles exceptions thrown by a `try` block is placed within a `catch` statement and is called a `catch` block. Zero or more `catch` blocks are associated with a `try` block, and each `catch` block includes a type filter that determines the types of exceptions it handles. + +When an exception occurs in a `try` block, the system searches the associated `catch` blocks in the order they appear in application code, until it locates a `catch` block that handles the exception. A `catch` block handles an exception of type `T` if the type filter of the catch block specifies `T` or any type that `T` derives from. The system stops searching after it finds the first `catch` block that handles the exception. For this reason, in application code, a `catch` block that handles a type must be specified before a `catch` block that handles its base types, as demonstrated in the example that follows this section. A catch block that handles `System.Exception` is specified last. + +If none of the `catch` blocks associated with the current `try` block handle the exception, and the current `try` block is nested within other `try` blocks in the current call, the `catch` blocks associated with the next enclosing `try` block are searched. If no `catch` block for the exception is found, the system searches previous nesting levels in the current call. If no `catch` block for the exception is found in the current call, the exception is passed up the call stack, and the previous stack frame is searched for a `catch` block that handles the exception. The search of the call stack continues until the exception is handled or until no more frames exist on the call stack. If the top of the call stack is reached without finding a `catch` block that handles the exception, the default exception handler handles it and the application terminates. + +### F# try..with expression + +F# does not use `catch` blocks. Instead, a raised exception is pattern matched using a single `with` block. As this is an expression, rather than a statement, all paths must return the same type. To learn more, see [The try...with Expression](/dotnet/fsharp/language-reference/exception-handling/the-try-with-expression). + +## Exception type features + +Exception types support the following features: + +- Human-readable text that describes the error. When an exception occurs, the runtime makes a text message available to inform the user of the nature of the error and to suggest action to resolve the problem. This text message is held in the property of the exception object. During the creation of the exception object, you can pass a text string to the constructor to describe the details of that particular exception. If no error message argument is supplied to the constructor, the default error message is used. For more information, see the property. + +- The state of the call stack when the exception was thrown. The property carries a stack trace that can be used to determine where the error occurs in the code. The stack trace lists all the called methods and the line numbers in the source file where the calls are made. + +## Exception class properties + +The class includes a number of properties that help identify the code location, the type, the help file, and the reason for the exception: , , , , , , , and . + +When a causal relationship exists between two or more exceptions, the property maintains this information. The outer exception is thrown in response to this inner exception. The code that handles the outer exception can use the information from the earlier inner exception to handle the error more appropriately. Supplementary information about the exception can be stored as a collection of key/value pairs in the property. + +The error message string that is passed to the constructor during the creation of the exception object should be localized and can be supplied from a resource file by using the class. For more information about localized resources, see the [Creating Satellite Assemblies](/dotnet/framework/resources/creating-satellite-assemblies-for-desktop-apps) and [Packaging and Deploying Resources](/dotnet/framework/resources/packaging-and-deploying-resources-in-desktop-apps) topics. + +To provide the user with extensive information about why the exception occurred, the property can hold a URL (or URN) to a help file. + +The class uses the HRESULT `COR_E_EXCEPTION`, which has the value 0x80131500. + +For a list of initial property values for an instance of the class, see the constructors. + +## Performance considerations + +Throwing or handling an exception consumes a significant amount of system resources and execution time. Throw exceptions only to handle truly extraordinary conditions, not to handle predictable events or flow control. For example, in some cases, such as when you're developing a class library, it's reasonable to throw an exception if a method argument is invalid, because you expect your method to be called with valid parameters. An invalid method argument, if it is not the result of a usage error, means that something extraordinary has occurred. Conversely, do not throw an exception if user input is invalid, because you can expect users to occasionally enter invalid data. Instead, provide a retry mechanism so users can enter valid input. Nor should you use exceptions to handle usage errors. Instead, use [assertions](/visualstudio/debugger/assertions-in-managed-code) to identify and correct usage errors. + +In addition, do not throw an exception when a return code is sufficient; do not convert a return code to an exception; and do not routinely catch an exception, ignore it, and then continue processing. + +## Re-throw an exception + +In many cases, an exception handler simply wants to pass the exception on to the caller. This most often occurs in: + +- A class library that in turn wraps calls to methods in the .NET class library or other class libraries. + +- An application or library that encounters a fatal exception. The exception handler can log the exception and then re-throw the exception. + +The recommended way to re-throw an exception is to simply use the [throw](/dotnet/csharp/language-reference/keywords/throw) statement in C#, the [reraise](/dotnet/fsharp/language-reference/exception-handling/the-raise-function.md#reraising-an-exception) function in F#, and the [Throw](/dotnet/visual-basic/language-reference/statements/throw-statement) statement in Visual Basic without including an expression. This ensures that all call stack information is preserved when the exception is propagated to the caller. The following example illustrates this. A string extension method, `FindOccurrences`, wraps one or more calls to without validating its arguments beforehand. + +:::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/rethrow1.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/rethrow1.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/rethrow1.vb" id="Snippet6"::: + +A caller then calls `FindOccurrences` twice. In the second call to `FindOccurrences`, the caller passes a `null` as the search string, which causes the method to throw an exception. This exception is handled by the `FindOccurrences` method and passed back to the caller. Because the throw statement is used with no expression, the output from the example shows that the call stack is preserved. + +:::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/rethrow1.cs" id="Snippet7"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/rethrow1.fs" id="Snippet7"::: +:::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/rethrow1.vb" id="Snippet7"::: + +In contrast, if the exception is re-thrown by using this statement: + +```csharp +throw e; +``` + +```vb +Throw e +``` + +```fsharp +raise e +``` + +...then the full call stack is not preserved, and the example would generate the following output: + +```output +'a' occurs at the following character positions: 4, 7, 15 + +An exception (ArgumentNullException) occurred. +Message: + Value cannot be null. +Parameter name: value + +Stack Trace: + at Library.FindOccurrences(String s, String f) + at Example.Main() +``` + +A slightly more cumbersome alternative is to throw a new exception, and to preserve the original exception's call stack information in an inner exception. The caller can then use the new exception's property to retrieve stack frame and other information about the original exception. In this case, the throw statement is: + +:::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/rethrow3.cs" id="Snippet8"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/rethrow3.fs" id="Snippet8"::: +:::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/rethrow3.vb" id="Snippet8"::: + +The user code that handles the exception has to know that the property contains information about the original exception, as the following exception handler illustrates. + +:::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/rethrow3.cs" id="Snippet9"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/rethrow3.fs" id="Snippet9"::: +:::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/rethrow3.vb" id="Snippet9"::: + +## Choose standard exceptions + +When you have to throw an exception, you can often use an existing exception type in .NET instead of implementing a custom exception. You should use a standard exception type under these two conditions: + +- You're throwing an exception that is caused by a usage error (that is, by an error in program logic made by the developer who is calling your method). Typically, you would throw an exception such as , , , or . The string you supply to the exception object's constructor when instantiating the exception object should describe the error so that the developer can fix it. For more information, see the property. + +- You're handling an error that can be communicated to the caller with an existing .NET exception. You should throw the most derived exception possible. For example, if a method requires an argument to be a valid member of an enumeration type, you should throw an (the most derived class) rather than an . + +The following table lists common exception types and the conditions under which you would throw them. + +|Exception|Condition| +|---------------|---------------| +||A non-null argument that is passed to a method is invalid.| +||An argument that is passed to a method is `null`.| +||An argument is outside the range of valid values.| +||Part of a directory path is not valid.| +||The denominator in an integer or division operation is zero.| +||A drive is unavailable or does not exist.| +||A file does not exist.| +||A value is not in an appropriate format to be converted from a string by a conversion method such as `Parse`.| +||An index is outside the bounds of an array or collection.| +||A method call is invalid in an object's current state.| +||The specified key for accessing a member in a collection cannot be found.| +||A method or operation is not implemented.| +||A method or operation is not supported.| +||An operation is performed on an object that has been disposed.| +||An arithmetic, casting, or conversion operation results in an overflow.| +||A path or file name exceeds the maximum system-defined length.| +||The operation is not supported on the current platform.| +||An array with the wrong number of dimensions is passed to a method.| +||The time interval allotted to an operation has expired.| +||An invalid Uniform Resource Identifier (URI) is used.| + +## Implement custom exceptions + +In the following cases, using an existing .NET exception to handle an error condition is not adequate: + +- When the exception reflects a unique program error that cannot be mapped to an existing .NET exception. + +- When the exception requires handling that is different from the handling that is appropriate for an existing .NET exception, or the exception must be disambiguated from a similar exception. For example, if you throw an exception when parsing the numeric representation of a string that is out of range of the target integral type, you would not want to use the same exception for an error that results from the caller not supplying the appropriate constrained values when calling the method. + +The class is the base class of all exceptions in .NET. Many derived classes rely on the inherited behavior of the members of the class; they do not override the members of , nor do they define any unique members. + +To define your own exception class: + +1. Define a class that inherits from . If necessary, define any unique members needed by your class to provide additional information about the exception. For example, the class includes a property that specifies the name of the parameter whose argument caused the exception, and the property includes a property that indicates the time-out interval. + +2. If necessary, override any inherited members whose functionality you want to change or modify. Note that most existing derived classes of do not override the behavior of inherited members. + +3. Determine whether your custom exception object is serializable. Serialization enables you to save information about the exception and permits exception information to be shared by a server and a client proxy in a remoting context. To make the exception object serializable, mark it with the attribute. + +4. Define the constructors of your exception class. Typically, exception classes have one or more of the following constructors: + + - , which uses default values to initialize the properties of a new exception object. + + - , which initializes a new exception object with a specified error message. + + - , which initializes a new exception object with a specified error message and inner exception. + + - , which is a `protected` constructor that initializes a new exception object from serialized data. You should implement this constructor if you've chosen to make your exception object serializable. + +The following example illustrates the use of a custom exception class. It defines a `NotPrimeException` exception that is thrown when a client tries to retrieve a sequence of prime numbers by specifying a starting number that is not prime. The exception defines a new property, `NonPrime`, that returns the non-prime number that caused the exception. Besides implementing a protected parameterless constructor and a constructor with and parameters for serialization, the `NotPrimeException` class defines three additional constructors to support the `NonPrime` property. Each constructor calls a base class constructor in addition to preserving the value of the non-prime number. The `NotPrimeException` class is also marked with the attribute. + +:::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/notprimeexception.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/notprimeexception.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/notprimeexception.vb" id="Snippet1"::: + +The `PrimeNumberGenerator` class shown in the following example uses the Sieve of Eratosthenes to calculate the sequence of prime numbers from 2 to a limit specified by the client in the call to its class constructor. The `GetPrimesFrom` method returns all prime numbers that are greater than or equal to a specified lower limit, but throws a `NotPrimeException` if that lower limit is not a prime number. + +:::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/primenumbergenerator.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/primenumbergenerator.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/primenumbergenerator.vb" id="Snippet2"::: + +The following example makes two calls to the `GetPrimesFrom` method with non-prime numbers, one of which crosses application domain boundaries. In both cases, the exception is thrown and successfully handled in client code. + +:::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/example.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/example.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/example.vb" id="Snippet3"::: + +## Examples + +The following example demonstrates a `catch` (`with` in F#) block that is defined to handle errors. This `catch` block also catches errors, because derives from and there is no `catch` block explicitly defined for errors. + +:::code language="csharp" source="~/snippets/csharp/System/Exception/Overview/catchexception.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Exception/Overview/catchexception.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Exception/Overview/catchexception.vb" id="Snippet1"::: + + ]]> + Handling and Throwing Exceptions Packaging and Deploying Resources in Desktop Apps Assertions in Managed Code @@ -401,7 +623,35 @@ Gets a collection of key/value pairs that provide additional user-defined information about the exception. An object that implements the interface and contains a collection of user-defined key/value pairs. The default is an empty collection. - For more information about this API, see Supplemental API remarks for Exception.Data. + + object returned by the property to store and retrieve supplementary information relevant to the exception. The information is in the form of an arbitrary number of user-defined key/value pairs. The key component of each key/value pair is typically an identifying string, whereas the value component of the pair can be any type of object. + +## Key/value pair security + +The key/value pairs stored in the collection returned by the property are not secure. If your application calls a nested series of routines, and each routine contains exception handlers, the resulting call stack contains a hierarchy of those exception handlers. If a lower-level routine throws an exception, any upper-level exception handler in the call stack hierarchy can read and/or modify the key/value pairs stored in the collection by any other exception handler. This means you must guarantee that the information in the key/value pairs is not confidential and that your application will operate correctly if the information in the key/value pairs is corrupted. + +## Key conflicts + +A key conflict occurs when different exception handlers specify the same key to access a key/value pair. Use caution when developing your application because the consequence of a key conflict is that lower-level exception handlers can inadvertently communicate with higher-level exception handlers, and this communication might cause subtle program errors. However, if you are cautious you can use key conflicts to enhance your application. + +## Avoid key conflicts + +Avoid key conflicts by adopting a naming convention to generate unique keys for key/value pairs. For example, a naming convention might yield a key that consists of the period-delimited name of your application, the method that provides supplementary information for the pair, and a unique identifier. + +Suppose two applications, named Products and Suppliers, each has a method named Sales. The Sales method in the Products application provides the identification number (the stock keeping unit or SKU) of a product. The Sales method in the Suppliers application provides the identification number, or SID, of a supplier. Consequently, the naming convention for this example yields the keys, "Products.Sales.SKU" and "Suppliers.Sales.SID". + +## Exploit key conflicts + +Exploit key conflicts by using the presence of one or more special, prearranged keys to control processing. Suppose, in one scenario, the highest level exception handler in the call stack hierarchy catches all exceptions thrown by lower-level exception handlers. If a key/value pair with a special key exists, the high-level exception handler formats the remaining key/value pairs in the object in some nonstandard way; otherwise, the remaining key/value pairs are formatted in some normal manner. + +Now suppose, in another scenario, the exception handler at each level of the call stack hierarchy catches the exception thrown by the next lower-level exception handler. In addition, each exception handler knows the collection returned by the property contains a set of key/value pairs that can be accessed with a prearranged set of keys. + +Each exception handler uses the prearranged set of keys to update the value component of the corresponding key/value pair with information unique to that exception handler. After the update process is complete, the exception handler throws the exception to the next higher-level exception handler. Finally, the highest level exception handler accesses the key/value pairs and displays the consolidated update information from all the lower-level exception handlers. + + ]]> + property. diff --git a/xml/System/FlagsAttribute.xml b/xml/System/FlagsAttribute.xml index 6c3b9bdc0e9..6254b9f12cc 100644 --- a/xml/System/FlagsAttribute.xml +++ b/xml/System/FlagsAttribute.xml @@ -55,7 +55,59 @@ Indicates that an enumeration can be treated as a bit field; that is, a set of flags. - For more information about this API, see Supplemental API remarks for FlagsAttribute. + + attribute indicates that an enumeration can be treated as a bit field; that is, a set of flags. + +Bit fields are generally used for lists of elements that might occur in combination, whereas enumeration constants are generally used for lists of mutually exclusive elements. Therefore, bit fields are designed to be combined with a bitwise `OR` operation to generate unnamed values, whereas enumerated constants are not. Languages vary in their use of bit fields compared to enumeration constants. + +## Attributes of the FlagsAttribute + + is applied to this class, and its property specifies `false`. This attribute can only be applied to enumerations. + +## Guidelines for FlagsAttribute and enum + +- Use the custom attribute for an enumeration only if a bitwise operation (AND, OR, EXCLUSIVE OR) is to be performed on a numeric value. + +- Define enumeration constants in powers of two, that is, 1, 2, 4, 8, and so on. This means the individual flags in combined enumeration constants do not overlap. + +- Consider creating an enumerated constant for commonly used flag combinations. For example, if you have an enumeration used for file I/O operations that contains the enumerated constants `Read = 1` and `Write = 2`, consider creating the enumerated constant `ReadWrite = Read OR Write`, which combines the `Read` and `Write` flags. In addition, the bitwise OR operation used to combine the flags might be considered an advanced concept in some circumstances that should not be required for simple tasks. + +- Use caution if you define a negative number as a flag enumerated constant because many flag positions might be set to 1, which might make your code confusing and encourage coding errors. + +- A convenient way to test whether a flag is set in a numeric value is to perform a bitwise AND operation between the numeric value and the flag enumerated constant, which sets all bits in the numeric value to zero that do not correspond to the flag, then test whether the result of that operation is equal to the flag enumerated constant. + +- Use `None` as the name of the flag enumerated constant whose value is zero. You cannot use the `None` enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. However, you can perform a logical, not a bitwise, comparison between the numeric value and the `None` enumerated constant to determine whether any bits in the numeric value are set. + + If you create a value enumeration instead of a flags enumeration, it is still worthwhile to create a `None` enumerated constant. The reason is that by default the memory used for the enumeration is initialized to zero by the common language runtime. Consequently, if you do not define a constant whose value is zero, the enumeration will contain an illegal value when it is created. + + If there is an obvious default case your application needs to represent, consider using an enumerated constant whose value is zero to represent the default. If there is no default case, consider using an enumerated constant whose value is zero that means the case that is not represented by any of the other enumerated constants. + +- Do not define an enumeration value solely to mirror the state of the enumeration itself. For example, do not define an enumerated constant that merely marks the end of the enumeration. If you need to determine the last value of the enumeration, check for that value explicitly. In addition, you can perform a range check for the first and last enumerated constant if all values within the range are valid. + +- Do not specify enumerated constants that are reserved for future use. + +- When you define a method or property that takes an enumerated constant as a value, consider validating the value. The reason is that you can cast a numeric value to the enumeration type even if that numeric value is not defined in the enumeration. + +## Examples + +The following example illustrates the use of the `FlagsAttribute` attribute and shows the effect on the method of using `FlagsAttribute` on an declaration. + +:::code language="csharp" source="~/snippets/csharp/System/FlagsAttribute/Overview/flags.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/FlagsAttribute/Overview/flags.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/FlagsAttribute/Overview/flags.vb" id="Snippet1"::: + +The preceding example defines two color-related enumerations, `SingleHue` and `MultiHue`. The latter has the `FlagsAttribute` attribute; the former does not. The example shows the difference in behavior when a range of integers, including integers that do not represent underlying values of the enumeration type, are cast to the enumeration type and their string representations displayed. For example, note that 3 cannot be represented as a `SingleHue` value because 3 is not the underlying value of any `SingleHue` member, whereas the `FlagsAttribute` attribute makes it possible to represent 3 as a `MultiHue` value of `Black, Red`. + +The following example defines another enumeration with the `FlagsAttribute` attribute and shows how to use bitwise logical and equality operators to determine whether one or more bit fields are set in an enumeration value. You can also use the method to do that, but that is not shown in this example. + +:::code language="csharp" source="~/snippets/csharp/System/FlagsAttribute/Overview/flags1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/FlagsAttribute/Overview/flags1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/FlagsAttribute/Overview/flags1.vb" id="Snippet2"::: + + ]]> + diff --git a/xml/System/GC.xml b/xml/System/GC.xml index 7cb4debcad1..4262436d341 100644 --- a/xml/System/GC.xml +++ b/xml/System/GC.xml @@ -55,7 +55,47 @@ Controls the system garbage collector, a service that automatically reclaims unused memory. - For more information about this API, see Supplemental API remarks for GC. + + class controls the garbage collector. The garbage collector is a common language runtime component that controls the allocation and release of managed memory. The methods in this class influence when garbage collection is performed on an object and when resources allocated by an object are released. Properties in this class provide information about the total amount of memory available in the system and the age category, or generation, of memory allocated to an object. + +The garbage collector tracks and reclaims objects allocated in managed memory. Periodically, the garbage collector performs garbage collection to reclaim memory allocated to objects for which there are no valid references. Garbage collection happens automatically when a request for memory cannot be satisfied using available free memory. Alternatively, an application can force garbage collection using the method. + +Garbage collection consists of the following steps: + +1. The garbage collector searches for managed objects that are referenced in managed code. +2. The garbage collector tries to finalize objects that are not referenced. +3. The garbage collector frees objects that are not referenced and reclaims their memory. + +## Unmanaged resources + +During a collection, the garbage collector will not free an object if it finds one or more references to the object in managed code. However, the garbage collector does not recognize references to an object from unmanaged code, and might free objects that are being used exclusively in unmanaged code unless explicitly prevented from doing so. The method provides a mechanism that prevents the garbage collector from collecting objects that are still in use in unmanaged code. + +Aside from managed memory allocations, implementations of the garbage collector do not maintain information about resources held by an object, such as file handles or database connections. When a type uses unmanaged resources that must be released before instances of the type are reclaimed, the type can implement a finalizer. + +In most cases, finalizers are implemented by overriding the method; however, types written in C# or C++ implement destructors, which compilers turn into an override of . In most cases, if an object has a finalizer, the garbage collector calls it prior to freeing the object. However, the garbage collector is not required to call finalizers in all situations; for example, the method explicitly prevents an object's finalizer from being called. Also, the garbage collector is not required to use a specific thread to finalize objects, or guarantee the order in which finalizers are called for objects that reference each other but are otherwise available for garbage collection. + +In scenarios where resources must be released at a specific time, classes can implement the interface, which contains the method that performs resource management and cleanup tasks. Classes that implement must specify, as part of their class contract, if and when class consumers call the method to clean up the object. The garbage collector does not, by default, call the method; however, implementations of the method can call methods in the class to customize the finalization behavior of the garbage collector. + +For more information on object finalization and the dispose pattern, see [Cleaning Up Unmanaged Resources](/dotnet/standard/garbage-collection/unmanaged). + +## Object aging and generations + +The garbage collector in the common language runtime supports object aging using generations. A generation is a unit of measure of the relative age of objects in memory. The generation number, or age, of an object indicates the generation to which an object belongs. Objects created more recently are part of newer generations, and have lower generation numbers than objects created earlier in the application life cycle. Objects in the most recent generation are in generation 0. This implementation of the garbage collector supports three generations of objects, generations 0, 1, and 2. You can retrieve the value of the property to determine the maximum generation number supported by the system. + +Object aging allows applications to target garbage collection at a specific set of generations rather than requiring the garbage collector to evaluate all generations. Overloads of the method that include a `generation` parameter allow you to specify the oldest generation to be garbage collected. + +## Disallowing garbage collection + +The garbage collector supports a no GC region latency mode that can be used during the execution of critical paths in which garbage collection can adversely affect an app's performance. The no GC region latency mode requires that you specify an amount of memory that can be allocated without interference from the garbage collector. If the runtime can allocate that memory, the runtime will not perform a garbage collection while code in the critical path is executing. + +You define the beginning of the critical path of the no GC region by calling one of the overloads of the . You specify the end of its critical path by calling the method. + +You cannot nest calls to the method, and you should only call the method if the runtime is currently in no GC region latency mode. In other words, you should not call multiple times (after the first method call, subsequent calls will not succeed), and you should not expect calls to to succeed just because the first call to succeeded. + + ]]> +