diff --git a/snippets/csharp/System/Int32/Overview/Formatting1.cs b/snippets/csharp/System/Int32/Overview/Formatting1.cs new file mode 100644 index 00000000000..6b68dcf58ba --- /dev/null +++ b/snippets/csharp/System/Int32/Overview/Formatting1.cs @@ -0,0 +1,57 @@ +using System; + +public class Example1 +{ + public static void Main() + { + CallToString(); + Console.WriteLine("-----"); + CallConvert(); + } + + private static void CallToString() + { + // + int[] numbers = { -1403, 0, 169, 1483104 }; + foreach (int number in numbers) + { + // Display value using default formatting. + Console.Write("{0,-8} --> ", number.ToString()); + // Display value with 3 digits and leading zeros. + Console.Write("{0,11:D3}", number); + // Display value with 1 decimal digit. + Console.Write("{0,13:N1}", number); + // Display value as hexadecimal. + Console.Write("{0,12:X2}", number); + // Display value with eight hexadecimal digits. + Console.WriteLine("{0,14:X8}", number); + } + // The example displays the following output: + // -1403 --> -1403 -1,403.0 FFFFFA85 FFFFFA85 + // 0 --> 000 0.0 00 00000000 + // 169 --> 169 169.0 A9 000000A9 + // 1483104 --> 1483104 1,483,104.0 16A160 0016A160 + // + } + + private static void CallConvert() + { + // + int[] numbers = { -146, 11043, 2781913 }; + Console.WriteLine("{0,8} {1,32} {2,11} {3,10}", + "Value", "Binary", "Octal", "Hex"); + foreach (int number in numbers) + { + Console.WriteLine("{0,8} {1,32} {2,11} {3,10}", + number, Convert.ToString(number, 2), + Convert.ToString(number, 8), + Convert.ToString(number, 16)); + } + // The example displays the following output: + // Value Binary Octal Hex + // -146 11111111111111111111111101101110 37777777556 ffffff6e + // 11043 10101100100011 25443 2b23 + // 2781913 1010100111001011011001 12471331 2a72d9 + // + } +} diff --git a/snippets/csharp/System/Int32/Overview/Instantiate1.cs b/snippets/csharp/System/Int32/Overview/Instantiate1.cs new file mode 100644 index 00000000000..84958e6bcd7 --- /dev/null +++ b/snippets/csharp/System/Int32/Overview/Instantiate1.cs @@ -0,0 +1,105 @@ +using System; +using System.Numerics; + +public class Example +{ + public static void Main() + { + InstantiateByAssignment(); + Console.WriteLine("----"); + InstantiateByNarrowingConversion(); + Console.WriteLine("----"); + Parse(); + Console.WriteLine("----"); + InstantiateByWideningConversion(); + } + + private static void InstantiateByAssignment() + { + // + int number1 = 64301; + int number2 = 25548612; + // + Console.WriteLine($"{number1} - {number2}"); + } + + private static void InstantiateByNarrowingConversion() + { + // + long lNumber = 163245617; + try { + int number1 = (int) lNumber; + Console.WriteLine(number1); + } + catch (OverflowException) { + Console.WriteLine($"{lNumber} is out of range of an Int32."); + } + + double dbl2 = 35901.997; + try { + int number2 = (int) dbl2; + Console.WriteLine(number2); + } + catch (OverflowException) { + Console.WriteLine($"{dbl2} is out of range of an Int32."); + } + + BigInteger bigNumber = 132451; + try { + int number3 = (int) bigNumber; + Console.WriteLine(number3); + } + catch (OverflowException) { + Console.WriteLine($"{bigNumber} is out of range of an Int32."); + } + // The example displays the following output: + // 163245617 + // 35902 + // 132451 + // + } + + private static void Parse() + { + // + string string1 = "244681"; + try { + int number1 = Int32.Parse(string1); + Console.WriteLine(number1); + } + catch (OverflowException) { + Console.WriteLine($"'{string1}' is out of range of a 32-bit integer."); + } + catch (FormatException) { + Console.WriteLine($"The format of '{string1}' is invalid."); + } + + string string2 = "F9A3C"; + try { + int number2 = Int32.Parse(string2, + System.Globalization.NumberStyles.HexNumber); + Console.WriteLine(number2); + } + catch (OverflowException) { + Console.WriteLine($"'{string2}' is out of range of a 32-bit integer."); + } + catch (FormatException) { + Console.WriteLine($"The format of '{string2}' is invalid."); + } + // The example displays the following output: + // 244681 + // 1022524 + // + } + + private static void InstantiateByWideningConversion() + { + // + sbyte value1 = 124; + short value2 = 1618; + + int number1 = value1; + int number2 = value2; + // + } +} diff --git a/snippets/csharp/System/Int32/Overview/Project.csproj b/snippets/csharp/System/Int32/Overview/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Int32/Overview/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Int64/Overview/Project.csproj b/snippets/csharp/System/Int64/Overview/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Int64/Overview/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Int64/Overview/formatting1.cs b/snippets/csharp/System/Int64/Overview/formatting1.cs new file mode 100644 index 00000000000..f4dedc16381 --- /dev/null +++ b/snippets/csharp/System/Int64/Overview/formatting1.cs @@ -0,0 +1,65 @@ +using System; + +public class Example1 +{ + public static void Main() + { + CallToString(); + Console.WriteLine("-----"); + CallConvert(); + } + + private static void CallToString() + { + // + long[] numbers = { -1403, 0, 169, 1483104 }; + foreach (var number in numbers) + { + // Display value using default formatting. + Console.Write("{0,-8} --> ", number.ToString()); + // Display value with 3 digits and leading zeros. + Console.Write("{0,8:D3}", number); + // Display value with 1 decimal digit. + Console.Write("{0,13:N1}", number); + // Display value as hexadecimal. + Console.Write("{0,18:X2}", number); + // Display value with eight hexadecimal digits. + Console.WriteLine("{0,18:X8}", number); + } + // The example displays the following output: + // -1403 --> -1403 -1,403.0 FFFFFFFFFFFFFA85 FFFFFFFFFFFFFA85 + // 0 --> 000 0.0 00 00000000 + // 169 --> 169 169.0 A9 000000A9 + // 1483104 --> 1483104 1,483,104.0 16A160 0016A160 + // + } + + private static void CallConvert() + { + // + long[] numbers = { -146, 11043, 2781913 }; + foreach (var number in numbers) + { + Console.WriteLine($"{number} (Base 10):"); + Console.WriteLine($" Binary: {Convert.ToString(number, 2)}"); + Console.WriteLine($" Octal: {Convert.ToString(number, 8)}"); + Console.WriteLine($" Hex: {Convert.ToString(number, 16)}{Environment.NewLine}"); + } + // The example displays the following output: + // -146 (Base 10): + // Binary: 1111111111111111111111111111111111111111111111111111111101101110 + // Octal: 1777777777777777777556 + // Hex: ffffffffffffff6e + // + // 11043 (Base 10): + // Binary: 10101100100011 + // Octal: 25443 + // Hex: 2b23 + // + // 2781913 (Base 10): + // Binary: 1010100111001011011001 + // Octal: 12471331 + // Hex: 2a72d9 + // + } +} diff --git a/snippets/csharp/System/Int64/Overview/instantiate1.cs b/snippets/csharp/System/Int64/Overview/instantiate1.cs new file mode 100644 index 00000000000..ffe7cc22985 --- /dev/null +++ b/snippets/csharp/System/Int64/Overview/instantiate1.cs @@ -0,0 +1,107 @@ +using System; +using System.Numerics; + +public class Example +{ + public static void Main() + { + InstantiateByAssignment(); + Console.WriteLine("----"); + InstantiateByNarrowingConversion(); + Console.WriteLine("----"); + Parse(); + Console.WriteLine("----"); + InstantiateByWideningConversion(); + } + + private static void InstantiateByAssignment() + { + // + long number1 = -64301728; + long number2 = 255486129307; + // + Console.WriteLine($"{number1} - {number2}"); + } + + private static void InstantiateByNarrowingConversion() + { + // + ulong ulNumber = 163245617943825; + try { + long number1 = (long) ulNumber; + Console.WriteLine(number1); + } + catch (OverflowException) { + Console.WriteLine($"{ulNumber} is out of range of an Int64."); + } + + double dbl2 = 35901.997; + try { + long number2 = (long) dbl2; + Console.WriteLine(number2); + } + catch (OverflowException) { + Console.WriteLine($"{dbl2} is out of range of an Int64."); + } + + BigInteger bigNumber = (BigInteger) 1.63201978555e30; + try { + long number3 = (long) bigNumber; + Console.WriteLine(number3); + } + catch (OverflowException) { + Console.WriteLine($"{bigNumber} is out of range of an Int64."); + } + // The example displays the following output: + // 163245617943825 + // 35902 + // 1,632,019,785,549,999,969,612,091,883,520 is out of range of an Int64. + // + } + + private static void Parse() + { + // + string string1 = "244681903147"; + try { + long number1 = Int64.Parse(string1); + Console.WriteLine(number1); + } + catch (OverflowException) { + Console.WriteLine($"'{string1}' is out of range of a 64-bit integer."); + } + catch (FormatException) { + Console.WriteLine($"The format of '{string1}' is invalid."); + } + + string string2 = "F9A3CFF0A"; + try { + long number2 = Int64.Parse(string2, + System.Globalization.NumberStyles.HexNumber); + Console.WriteLine(number2); + } + catch (OverflowException) { + Console.WriteLine($"'{string2}' is out of range of a 64-bit integer."); + } + catch (FormatException) { + Console.WriteLine($"The format of '{string2}' is invalid."); + } + // The example displays the following output: + // 244681903147 + // 67012198154 + // + } + + private static void InstantiateByWideningConversion() + { + // + sbyte value1 = 124; + short value2 = 1618; + int value3 = Int32.MaxValue; + + long number1 = value1; + long number2 = value2; + long number3 = value3; + // + } +} diff --git a/snippets/csharp/System/InvalidCastException/Overview/Interface1.cs b/snippets/csharp/System/InvalidCastException/Overview/Interface1.cs new file mode 100644 index 00000000000..49ec5e280d1 --- /dev/null +++ b/snippets/csharp/System/InvalidCastException/Overview/Interface1.cs @@ -0,0 +1,21 @@ +// +using System; +using System.Globalization; + +public class InterfaceEx +{ + public static void Main() + { + var culture = CultureInfo.InvariantCulture; + IFormatProvider provider = culture; + + DateTimeFormatInfo dt = (DateTimeFormatInfo)provider; + } +} + +// The example displays the following output: +// Unhandled Exception: System.InvalidCastException: +// Unable to cast object of type 'System.Globalization.CultureInfo' to +// type 'System.Globalization.DateTimeFormatInfo'. +// at Example.Main() +// diff --git a/snippets/csharp/System/InvalidCastException/Overview/ToString1.cs b/snippets/csharp/System/InvalidCastException/Overview/ToString1.cs new file mode 100644 index 00000000000..121c1585e46 --- /dev/null +++ b/snippets/csharp/System/InvalidCastException/Overview/ToString1.cs @@ -0,0 +1,11 @@ +// +public class StringEx +{ + public static void Main() + { + object value = 12; + // Cast throws an InvalidCastException exception. + string s = (string)value; + } +} +// diff --git a/snippets/csharp/System/InvalidCastException/Overview/ToString2.cs b/snippets/csharp/System/InvalidCastException/Overview/ToString2.cs new file mode 100644 index 00000000000..8482f7dcbe7 --- /dev/null +++ b/snippets/csharp/System/InvalidCastException/Overview/ToString2.cs @@ -0,0 +1,15 @@ +// +using System; + +public class ToStringEx2 +{ + public static void Main() + { + object value = 12; + string s = value.ToString(); + Console.WriteLine(s); + } +} +// The example displays the following output: +// 12 +// diff --git a/snippets/csharp/System/InvalidCastException/Overview/basetoderived1.cs b/snippets/csharp/System/InvalidCastException/Overview/basetoderived1.cs new file mode 100644 index 00000000000..ff589249a2c --- /dev/null +++ b/snippets/csharp/System/InvalidCastException/Overview/basetoderived1.cs @@ -0,0 +1,66 @@ +// +using System; + +public class Person +{ + String _name; + + public String Name + { + get { return _name; } + set { _name = value; } + } +} + +public class PersonWithId : Person +{ + String _id; + + public string Id + { + get { return _id; } + set { _id = value; } + } +} + +public class Example +{ + public static void Main() + { + Person p = new Person(); + p.Name = "John"; + try { + PersonWithId pid = (PersonWithId) p; + Console.WriteLine("Conversion succeeded."); + } + catch (InvalidCastException) { + Console.WriteLine("Conversion failed."); + } + + PersonWithId pid1 = new PersonWithId(); + pid1.Name = "John"; + pid1.Id = "246"; + Person p1 = pid1; + try { + PersonWithId pid1a = (PersonWithId) p1; + Console.WriteLine("Conversion succeeded."); + } + catch (InvalidCastException) { + Console.WriteLine("Conversion failed."); + } + + Person p2 = null; + try { + PersonWithId pid2 = (PersonWithId) p2; + Console.WriteLine("Conversion succeeded."); + } + catch (InvalidCastException) { + Console.WriteLine("Conversion failed."); + } + } +} +// The example displays the following output: +// Conversion failed. +// Conversion succeeded. +// Conversion succeeded. +// diff --git a/snippets/csharp/System/InvalidCastException/Overview/iconvertible1.cs b/snippets/csharp/System/InvalidCastException/Overview/iconvertible1.cs new file mode 100644 index 00000000000..24d9bb1223a --- /dev/null +++ b/snippets/csharp/System/InvalidCastException/Overview/iconvertible1.cs @@ -0,0 +1,34 @@ +// +using System; + +public class IConvertibleEx +{ + public static void Main() + { + bool flag = true; + try + { + IConvertible conv = flag; + Char ch = conv.ToChar(null); + Console.WriteLine("Conversion succeeded."); + } + catch (InvalidCastException) + { + Console.WriteLine("Cannot convert a Boolean to a Char."); + } + + try + { + Char ch = Convert.ToChar(flag); + Console.WriteLine("Conversion succeeded."); + } + catch (InvalidCastException) + { + Console.WriteLine("Cannot convert a Boolean to a Char."); + } + } +} +// The example displays the following output: +// Cannot convert a Boolean to a Char. +// Cannot convert a Boolean to a Char. +// diff --git a/snippets/csharp/System/InvalidCastException/Overview/project.csproj b/snippets/csharp/System/InvalidCastException/Overview/project.csproj new file mode 100644 index 00000000000..dfdef3fd2a7 --- /dev/null +++ b/snippets/csharp/System/InvalidCastException/Overview/project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable1.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable1.cs new file mode 100644 index 00000000000..c642bbfa5b2 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable1.cs @@ -0,0 +1,19 @@ +// +using System; +using System.Linq; + +public class Example +{ + public static void Main() + { + int[] data = { 1, 2, 3, 4 }; + var average = data.Where(num => num > 4).Average(); + Console.Write("The average of numbers greater than 4 is {0}", + average); + } +} +// The example displays the following output: +// Unhandled Exception: System.InvalidOperationException: Sequence contains no elements +// at System.Linq.Enumerable.Average(IEnumerable`1 source) +// at Example.Main() +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable2.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable2.cs new file mode 100644 index 00000000000..e5b8dc2651e --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable2.cs @@ -0,0 +1,21 @@ +// +using System; +using System.Linq; + +public class EnumerableEx2 +{ + public static void Main() + { + int[] dbQueryResults = { 1, 2, 3, 4 }; + var moreThan4 = dbQueryResults.Where(num => num > 4); + + if (moreThan4.Any()) + Console.WriteLine($"Average value of numbers greater than 4: {moreThan4.Average()}:"); + else + // handle empty collection + Console.WriteLine("The dataset has no values greater than 4."); + } +} +// The example displays the following output: +// The dataset has no values greater than 4. +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable3.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable3.cs new file mode 100644 index 00000000000..7cc71ea6819 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable3.cs @@ -0,0 +1,21 @@ +// +using System; +using System.Linq; + +public class EnumerableEx3 +{ + public static void Main() + { + int[] dbQueryResults = { 1, 2, 3, 4 }; + + var firstNum = dbQueryResults.First(n => n > 4); + + Console.WriteLine($"The first value greater than 4 is {firstNum}"); + } +} +// The example displays the following output: +// Unhandled Exception: System.InvalidOperationException: +// Sequence contains no matching element +// at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate) +// at Example.Main() +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable4.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable4.cs new file mode 100644 index 00000000000..52bc3a5ce79 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable4.cs @@ -0,0 +1,21 @@ +// +using System; +using System.Linq; + +public class EnumerableEx4 +{ + public static void Main() + { + int[] dbQueryResults = { 1, 2, 3, 4 }; + + var firstNum = dbQueryResults.FirstOrDefault(n => n > 4); + + if (firstNum == 0) + Console.WriteLine("No value is greater than 4."); + else + Console.WriteLine($"The first value greater than 4 is {firstNum}"); + } +} +// The example displays the following output: +// No value is greater than 4. +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable5.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable5.cs new file mode 100644 index 00000000000..a91f0e481f0 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable5.cs @@ -0,0 +1,22 @@ +// +using System; +using System.Linq; + +public class EnumerableEx5 +{ + public static void Main() + { + int[] dbQueryResults = { 1, 2, 3, 4 }; + + var singleObject = dbQueryResults.Single(value => value > 4); + + // Display results. + Console.WriteLine($"{singleObject} is the only value greater than 4"); + } +} +// The example displays the following output: +// Unhandled Exception: System.InvalidOperationException: +// Sequence contains no matching element +// at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate) +// at Example.Main() +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable6.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable6.cs new file mode 100644 index 00000000000..8d2c1be0634 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable6.cs @@ -0,0 +1,25 @@ +// +using System; +using System.Linq; + +public class EnumerableEx6 +{ + public static void Main() + { + int[] dbQueryResults = { 1, 2, 3, 4 }; + + var singleObject = dbQueryResults.SingleOrDefault(value => value > 2); + + if (singleObject != 0) + Console.WriteLine($"{singleObject} is the only value greater than 2"); + else + // Handle an empty collection. + Console.WriteLine("No value is greater than 2"); + } +} +// The example displays the following output: +// Unhandled Exception: System.InvalidOperationException: +// Sequence contains more than one matching element +// at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) +// at Example.Main() +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating1.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating1.cs new file mode 100644 index 00000000000..d13af74d0ec --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating1.cs @@ -0,0 +1,30 @@ +// +using System; +using System.Collections.Generic; + +public class IteratingEx1 +{ + public static void Main() + { + var numbers = new List() { 1, 2, 3, 4, 5 }; + foreach (var number in numbers) + { + int square = (int)Math.Pow(number, 2); + Console.WriteLine($"{number}^{square}"); + Console.WriteLine($"Adding {square} to the collection..."); + Console.WriteLine(); + numbers.Add(square); + } + } +} +// The example displays the following output: +// 1^1 +// Adding 1 to the collection... +// +// +// Unhandled Exception: System.InvalidOperationException: Collection was modified; +// enumeration operation may not execute. +// at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +// at System.Collections.Generic.List`1.Enumerator.MoveNextRare() +// at Example.Main() +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating2.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating2.cs new file mode 100644 index 00000000000..b68b322ffa4 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating2.cs @@ -0,0 +1,44 @@ +// +using System; +using System.Collections.Generic; + +public class IteratingEx2 +{ + public static void Main() + { + var numbers = new List() { 1, 2, 3, 4, 5 }; + + int upperBound = numbers.Count - 1; + for (int ctr = 0; ctr <= upperBound; ctr++) + { + int square = (int)Math.Pow(numbers[ctr], 2); + Console.WriteLine($"{numbers[ctr]}^{square}"); + Console.WriteLine($"Adding {square} to the collection..."); + Console.WriteLine(); + numbers.Add(square); + } + + Console.WriteLine("Elements now in the collection: "); + foreach (var number in numbers) + Console.Write("{0} ", number); + } +} +// The example displays the following output: +// 1^1 +// Adding 1 to the collection... +// +// 2^4 +// Adding 4 to the collection... +// +// 3^9 +// Adding 9 to the collection... +// +// 4^16 +// Adding 16 to the collection... +// +// 5^25 +// Adding 25 to the collection... +// +// Elements now in the collection: +// 1 2 3 4 5 1 4 9 16 25 +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating3.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating3.cs new file mode 100644 index 00000000000..b7d8b78aca7 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating3.cs @@ -0,0 +1,31 @@ +// +using System; +using System.Collections.Generic; + +public class IteratingEx3 +{ + public static void Main() + { + var numbers = new List() { 1, 2, 3, 4, 5 }; + var temp = new List(); + + // Square each number and store it in a temporary collection. + foreach (var number in numbers) + { + int square = (int)Math.Pow(number, 2); + temp.Add(square); + } + + // Combine the numbers into a single array. + int[] combined = new int[numbers.Count + temp.Count]; + Array.Copy(numbers.ToArray(), 0, combined, 0, numbers.Count); + Array.Copy(temp.ToArray(), 0, combined, numbers.Count, temp.Count); + + // Iterate the array. + foreach (var value in combined) + Console.Write("{0} ", value); + } +} +// The example displays the following output: +// 1 2 3 4 5 1 4 9 16 25 +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort1.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort1.cs new file mode 100644 index 00000000000..39fedd45e0d --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort1.cs @@ -0,0 +1,42 @@ +// +using System; +using System.Collections.Generic; + +public class Person1 +{ + public Person1(string fName, string lName) + { + FirstName = fName; + LastName = lName; + } + + public string FirstName { get; set; } + public string LastName { get; set; } +} + +public class ListSortEx1 +{ + public static void Main() + { + var people = new List(); + + people.Add(new Person1("John", "Doe")); + people.Add(new Person1("Jane", "Doe")); + people.Sort(); + foreach (var person in people) + Console.WriteLine($"{person.FirstName} {person.LastName}"); + } +} +// The example displays the following output: +// Unhandled Exception: System.InvalidOperationException: Failed to compare two elements in the array. ---> +// System.ArgumentException: At least one object must implement IComparable. +// at System.Collections.Comparer.Compare(Object a, Object b) +// at System.Collections.Generic.ArraySortHelper`1.SwapIfGreater(T[] keys, IComparer`1 comparer, Int32 a, Int32 b) +// at System.Collections.Generic.ArraySortHelper`1.DepthLimitedQuickSort(T[] keys, Int32 left, Int32 right, IComparer`1 comparer, Int32 depthLimit) +// at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer) +// --- End of inner exception stack trace --- +// at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer) +// at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer) +// at System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer) +// at Example.Main() +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort2.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort2.cs new file mode 100644 index 00000000000..480f962e20f --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort2.cs @@ -0,0 +1,39 @@ +// +using System; +using System.Collections.Generic; + +public class Person2 : IComparable +{ + public Person2(String fName, String lName) + { + FirstName = fName; + LastName = lName; + } + + public String FirstName { get; set; } + public String LastName { get; set; } + + public int CompareTo(Person other) + { + return String.Format("{0} {1}", LastName, FirstName). + CompareTo(String.Format("{0} {1}", other.LastName, other.FirstName)); + } +} + +public class ListSortEx2 +{ + public static void Main() + { + var people = new List(); + + people.Add(new Person2("John", "Doe")); + people.Add(new Person2("Jane", "Doe")); + people.Sort(); + foreach (var person in people) + Console.WriteLine($"{person.FirstName} {person.LastName}"); + } +} +// The example displays the following output: +// Jane Doe +// John Doe +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort3.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort3.cs new file mode 100644 index 00000000000..83855abcedb --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort3.cs @@ -0,0 +1,42 @@ +// +using System; +using System.Collections.Generic; + +public class Person3 +{ + public Person3(String fName, String lName) + { + FirstName = fName; + LastName = lName; + } + + public String FirstName { get; set; } + public String LastName { get; set; } +} + +public class PersonComparer : IComparer +{ + public int Compare(Person3 x, Person3 y) + { + return String.Format("{0} {1}", x.LastName, x.FirstName). + CompareTo(String.Format("{0} {1}", y.LastName, y.FirstName)); + } +} + +public class ListSortEx3 +{ + public static void Main() + { + var people = new List(); + + people.Add(new Person3("John", "Doe")); + people.Add(new Person3("Jane", "Doe")); + people.Sort(new PersonComparer()); + foreach (var person in people) + Console.WriteLine($"{person.FirstName} {person.LastName}"); + } +} +// The example displays the following output: +// Jane Doe +// John Doe +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort4.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort4.cs new file mode 100644 index 00000000000..b570cc078ab --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort4.cs @@ -0,0 +1,39 @@ +// +using System; +using System.Collections.Generic; + +public class Person +{ + public Person(String fName, String lName) + { + FirstName = fName; + LastName = lName; + } + + public String FirstName { get; set; } + public String LastName { get; set; } +} + +public class ListSortEx4 +{ + public static void Main() + { + var people = new List(); + + people.Add(new Person("John", "Doe")); + people.Add(new Person("Jane", "Doe")); + people.Sort(PersonComparison); + foreach (var person in people) + Console.WriteLine($"{person.FirstName} {person.LastName}"); + } + + public static int PersonComparison(Person x, Person y) + { + return String.Format("{0} {1}", x.LastName, x.FirstName). + CompareTo(String.Format("{0} {1}", y.LastName, y.FirstName)); + } +} +// The example displays the following output: +// Jane Doe +// John Doe +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Nullable1.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Nullable1.cs new file mode 100644 index 00000000000..37eaffb7d5c --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Nullable1.cs @@ -0,0 +1,25 @@ +// +using System; +using System.Linq; + +public class NullableEx1 +{ + public static void Main() + { + var queryResult = new int?[] { 1, 2, null, 4 }; + var map = queryResult.Select(nullableInt => (int)nullableInt); + + // Display list. + foreach (var num in map) + Console.Write("{0} ", num); + Console.WriteLine(); + } +} +// The example displays the following output: +// 1 2 +// Unhandled Exception: System.InvalidOperationException: Nullable object must have a value. +// at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +// at Example.
b__0(Nullable`1 nullableInt) +// at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() +// at Example.Main() +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/Nullable2.cs b/snippets/csharp/System/InvalidOperationException/Overview/Other/Nullable2.cs new file mode 100644 index 00000000000..d8461cffa16 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/Nullable2.cs @@ -0,0 +1,27 @@ +// +using System; +using System.Linq; + +public class NullableEx2 +{ + public static void Main() + { + var queryResult = new int?[] { 1, 2, null, 4 }; + var numbers = queryResult.Select(nullableInt => (int)nullableInt.GetValueOrDefault()); + + // Display list using Nullable.HasValue. + foreach (var number in numbers) + Console.Write("{0} ", number); + Console.WriteLine(); + + numbers = queryResult.Select(nullableInt => (int) (nullableInt.HasValue ? nullableInt : -1)); + // Display list using Nullable.GetValueOrDefault. + foreach (var number in numbers) + Console.Write("{0} ", number); + Console.WriteLine(); + } +} +// The example displays the following output: +// 1 2 0 4 +// 1 2 -1 4 +// diff --git a/snippets/csharp/System/InvalidOperationException/Overview/Other/project.csproj b/snippets/csharp/System/InvalidOperationException/Overview/Other/project.csproj new file mode 100644 index 00000000000..dfdef3fd2a7 --- /dev/null +++ b/snippets/csharp/System/InvalidOperationException/Overview/Other/project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/NotSupportedException/Overview/BadState1.cs b/snippets/csharp/System/NotSupportedException/Overview/BadState1.cs new file mode 100644 index 00000000000..323cea83410 --- /dev/null +++ b/snippets/csharp/System/NotSupportedException/Overview/BadState1.cs @@ -0,0 +1,38 @@ +// +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +public class Example +{ + public static async Task Main() + { + Encoding enc = Encoding.Unicode; + String value = "This is a string to persist."; + Byte[] bytes = enc.GetBytes(value); + + FileStream fs = new FileStream(@".\TestFile.dat", + FileMode.Open, + FileAccess.Read); + Task t = fs.WriteAsync(enc.GetPreamble(), 0, enc.GetPreamble().Length); + Task t2 = t.ContinueWith((a) => fs.WriteAsync(bytes, 0, bytes.Length)); + await t2; + fs.Close(); + } +} +// The example displays the following output: +// Unhandled Exception: System.NotSupportedException: Stream does not support writing. +// at System.IO.Stream.BeginWriteInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state +// , Boolean serializeAsynchronously) +// at System.IO.FileStream.BeginWrite(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object sta +// teObject) +// at System.IO.Stream.<>c.b__53_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, +// Object state) +// at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMet +// hod, Func`3 endMethod) +// at System.IO.Stream.BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count) +// at System.IO.FileStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) +// at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count) +// at Example.Main() +// diff --git a/snippets/csharp/System/NotSupportedException/Overview/TestProp1.cs b/snippets/csharp/System/NotSupportedException/Overview/TestProp1.cs new file mode 100644 index 00000000000..7eaf7c84e92 --- /dev/null +++ b/snippets/csharp/System/NotSupportedException/Overview/TestProp1.cs @@ -0,0 +1,59 @@ +// +using System; +using System.IO; +using System.Threading.Tasks; + +public class TestPropEx1 +{ + public static async Task Main() + { + String name = @".\TestFile.dat"; + var fs = new FileStream(name, + FileMode.Create, + FileAccess.Write); + Console.WriteLine("Filename: {0}, Encoding: {1}", + name, await FileUtilities1.GetEncodingType(fs)); + } +} + +public class FileUtilities1 +{ + public enum EncodingType + { None = 0, Unknown = -1, Utf8 = 1, Utf16 = 2, Utf32 = 3 } + + public async static Task GetEncodingType(FileStream fs) + { + Byte[] bytes = new Byte[4]; + int bytesRead = await fs.ReadAsync(bytes, 0, 4); + if (bytesRead < 2) + return EncodingType.None; + + if (bytesRead >= 3 & (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)) + return EncodingType.Utf8; + + if (bytesRead == 4) + { + var value = BitConverter.ToUInt32(bytes, 0); + if (value == 0x0000FEFF | value == 0xFEFF0000) + return EncodingType.Utf32; + } + + var value16 = BitConverter.ToUInt16(bytes, 0); + if (value16 == (ushort)0xFEFF | value16 == (ushort)0xFFFE) + return EncodingType.Utf16; + + return EncodingType.Unknown; + } +} +// The example displays the following output: +// Unhandled Exception: System.NotSupportedException: Stream does not support reading. +// at System.IO.FileStream.BeginRead(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback callback, Object state) +// at System.IO.Stream.<>c.b__46_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, Object state) +// at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance, TArgs](TInstance thisRef, TArgs args, Func`5 beginMethod, Func`3 endMethod) +// at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count) +// at System.IO.FileStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) +// at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count) +// at FileUtilities.GetEncodingType(FileStream fs) in C:\Work\docs\program.cs:line 26 +// at Example.Main() in C:\Work\docs\program.cs:line 13 +// at Example.
() +// diff --git a/snippets/csharp/System/NotSupportedException/Overview/TestProp2.cs b/snippets/csharp/System/NotSupportedException/Overview/TestProp2.cs new file mode 100644 index 00000000000..795a01183ae --- /dev/null +++ b/snippets/csharp/System/NotSupportedException/Overview/TestProp2.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using System.Threading.Tasks; + +public class TestPropEx2 +{ + public static async Task Main() + { + String name = @".\TestFile.dat"; + var fs = new FileStream(name, + FileMode.Create, + FileAccess.Write); + Console.WriteLine("Filename: {0}, Encoding: {1}", + name, await FileUtilities.GetEncodingType(fs)); + } +} + +public class FileUtilities +{ + public enum EncodingType + { None = 0, Unknown = -1, Utf8 = 1, Utf16 = 2, Utf32 = 3 } + + // + public static async Task GetEncodingType(FileStream fs) + { + if (!fs.CanRead) + return EncodingType.Unknown; + + Byte[] bytes = new Byte[4]; + int bytesRead = await fs.ReadAsync(bytes, 0, 4); + if (bytesRead < 2) + return EncodingType.None; + + if (bytesRead >= 3 & (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)) + return EncodingType.Utf8; + + if (bytesRead == 4) + { + var value = BitConverter.ToUInt32(bytes, 0); + if (value == 0x0000FEFF | value == 0xFEFF0000) + return EncodingType.Utf32; + } + + var value16 = BitConverter.ToUInt16(bytes, 0); + if (value16 == (ushort)0xFEFF | value16 == (ushort)0xFFFE) + return EncodingType.Utf16; + + return EncodingType.Unknown; + } +} +// The example displays the following output: +// Filename: .\TestFile.dat, Encoding: Unknown +// diff --git a/snippets/csharp/System/NotSupportedException/Overview/project.csproj b/snippets/csharp/System/NotSupportedException/Overview/project.csproj new file mode 100644 index 00000000000..dfdef3fd2a7 --- /dev/null +++ b/snippets/csharp/System/NotSupportedException/Overview/project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Object/Equals/Project.csproj b/snippets/csharp/System/Object/Equals/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Object/Equals/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Object/Equals/equals2.cs b/snippets/csharp/System/Object/Equals/equals2.cs new file mode 100644 index 00000000000..e64ae9a67b8 --- /dev/null +++ b/snippets/csharp/System/Object/Equals/equals2.cs @@ -0,0 +1,91 @@ +// +using System; + +class Point2 +{ + protected int x, y; + + public Point2() : this(0, 0) + { } + + public Point2(int x, int y) + { + this.x = x; + this.y = y; + } + + public override bool Equals(Object obj) + { + //Check for null and compare run-time types. + if ((obj == null) || !this.GetType().Equals(obj.GetType())) + { + return false; + } + else + { + Point2 p = (Point2)obj; + return (x == p.x) && (y == p.y); + } + } + + public override int GetHashCode() + { + return HashCode.Combine(x, y); + } + + public override string ToString() + { + return String.Format("Point2({0}, {1})", x, y); + } +} + +sealed class Point3D : Point2 +{ + int z; + + public Point3D(int x, int y, int z) : base(x, y) + { + this.z = z; + } + + public override bool Equals(Object obj) + { + Point3D pt3 = obj as Point3D; + if (pt3 == null) + return false; + else + return base.Equals((Point2)obj) && z == pt3.z; + } + + public override int GetHashCode() + { + return HashCode.Combine(base.GetHashCode(), z); + } + + public override String ToString() + { + return String.Format("Point2({0}, {1}, {2})", x, y, z); + } +} + +class Example7 +{ + public static void Main() + { + Point2 point2D = new Point2(5, 5); + Point3D point3Da = new Point3D(5, 5, 2); + Point3D point3Db = new Point3D(5, 5, 2); + Point3D point3Dc = new Point3D(5, 5, -1); + + Console.WriteLine($"{point2D} = {point3Da}: {point2D.Equals(point3Da)}"); + Console.WriteLine($"{point2D} = {point3Db}: {point2D.Equals(point3Db)}"); + Console.WriteLine($"{point3Da} = {point3Db}: {point3Da.Equals(point3Db)}"); + Console.WriteLine($"{point3Da} = {point3Dc}: {point3Da.Equals(point3Dc)}"); + } +} +// The example displays the following output: +// Point2(5, 5) = Point2(5, 5, 2): False +// Point2(5, 5) = Point2(5, 5, 2): False +// Point2(5, 5, 2) = Point2(5, 5, 2): True +// Point2(5, 5, 2) = Point2(5, 5, -1): False +// diff --git a/snippets/csharp/System/Object/Equals/equals3.cs b/snippets/csharp/System/Object/Equals/equals3.cs new file mode 100644 index 00000000000..b03eeb114ab --- /dev/null +++ b/snippets/csharp/System/Object/Equals/equals3.cs @@ -0,0 +1,77 @@ +// +using System; + +class Rectangle +{ + private Point a, b; + + public Rectangle(int upLeftX, int upLeftY, int downRightX, int downRightY) + { + this.a = new Point(upLeftX, upLeftY); + this.b = new Point(downRightX, downRightY); + } + + public override bool Equals(Object obj) + { + // Perform an equality check on two rectangles (Point object pairs). + if (obj == null || GetType() != obj.GetType()) + return false; + Rectangle r = (Rectangle)obj; + return a.Equals(r.a) && b.Equals(r.b); + } + + public override int GetHashCode() + { + return Tuple.Create(a, b).GetHashCode(); + } + + public override String ToString() + { + return String.Format("Rectangle({0}, {1}, {2}, {3})", + a.x, a.y, b.x, b.y); + } +} + +class Point +{ + internal int x; + internal int y; + + public Point(int X, int Y) + { + this.x = X; + this.y = Y; + } + + public override bool Equals (Object obj) + { + // Performs an equality check on two points (integer pairs). + if (obj == null || GetType() != obj.GetType()) return false; + Point p = (Point)obj; + return (x == p.x) && (y == p.y); + } + + public override int GetHashCode() + { + return Tuple.Create(x, y).GetHashCode(); + } +} + +class Example +{ + public static void Main() + { + Rectangle r1 = new Rectangle(0, 0, 100, 200); + Rectangle r2 = new Rectangle(0, 0, 100, 200); + Rectangle r3 = new Rectangle(0, 0, 150, 200); + + Console.WriteLine($"{r1} = {r2}: {r1.Equals(r2)}"); + Console.WriteLine($"{r1} = {r3}: {r1.Equals(r3)}"); + Console.WriteLine($"{r2} = {r3}: {r2.Equals(r3)}"); + } +} +// The example displays the following output: +// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 100, 200): True +// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False +// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False +// diff --git a/snippets/csharp/System/Object/Equals/equals4.cs b/snippets/csharp/System/Object/Equals/equals4.cs new file mode 100644 index 00000000000..fae811a3bca --- /dev/null +++ b/snippets/csharp/System/Object/Equals/equals4.cs @@ -0,0 +1,60 @@ +// +using System; + +public struct Complex +{ + public double re, im; + + public override bool Equals(Object obj) + { + return obj is Complex && this == (Complex)obj; + } + + public override int GetHashCode() + { + return Tuple.Create(re, im).GetHashCode(); + } + + public static bool operator ==(Complex x, Complex y) + { + return x.re == y.re && x.im == y.im; + } + + public static bool operator !=(Complex x, Complex y) + { + return !(x == y); + } + + public override String ToString() + { + return String.Format("({0}, {1})", re, im); + } +} + +class MyClass +{ + public static void Main() + { + Complex cmplx1, cmplx2; + + cmplx1.re = 4.0; + cmplx1.im = 1.0; + + cmplx2.re = 2.0; + cmplx2.im = 1.0; + + Console.WriteLine($"{cmplx1} <> {cmplx2}: {cmplx1 != cmplx2}"); + Console.WriteLine($"{cmplx1} = {cmplx2}: {cmplx1.Equals(cmplx2)}"); + + cmplx2.re = 4.0; + + Console.WriteLine($"{cmplx1} = {cmplx2}: {cmplx1 == cmplx2}"); + Console.WriteLine($"{cmplx1} = {cmplx2}: {cmplx1.Equals(cmplx2)}"); + } +} +// The example displays the following output: +// (4, 1) <> (2, 1): True +// (4, 1) = (2, 1): False +// (4, 1) = (4, 1): True +// (4, 1) = (4, 1): True +// diff --git a/snippets/csharp/System/Object/Equals/equals_ref.cs b/snippets/csharp/System/Object/Equals/equals_ref.cs new file mode 100644 index 00000000000..8db6b1dc08a --- /dev/null +++ b/snippets/csharp/System/Object/Equals/equals_ref.cs @@ -0,0 +1,44 @@ +// +using System; + +// Define a reference type that does not override Equals. +public class Person +{ + private string personName; + + public Person(string name) + { + this.personName = name; + } + + public override string ToString() + { + return this.personName; + } +} + +public class Example1 +{ + public static void Main() + { + Person person1a = new Person("John"); + Person person1b = person1a; + Person person2 = new Person(person1a.ToString()); + + Console.WriteLine("Calling Equals:"); + Console.WriteLine($"person1a and person1b: {person1a.Equals(person1b)}"); + Console.WriteLine($"person1a and person2: {person1a.Equals(person2)}"); + + Console.WriteLine("\nCasting to an Object and calling Equals:"); + Console.WriteLine($"person1a and person1b: {((object) person1a).Equals((object) person1b)}"); + Console.WriteLine($"person1a and person2: {((object) person1a).Equals((object) person2)}"); + } +} +// The example displays the following output: +// person1a and person1b: True +// person1a and person2: False +// +// Casting to an Object and calling Equals: +// person1a and person1b: True +// person1a and person2: False +// diff --git a/snippets/csharp/System/Object/Equals/equals_static2.cs b/snippets/csharp/System/Object/Equals/equals_static2.cs index 08e940a3f12..d355f135482 100644 --- a/snippets/csharp/System/Object/Equals/equals_static2.cs +++ b/snippets/csharp/System/Object/Equals/equals_static2.cs @@ -1,7 +1,7 @@ // using System; -public class Example +public class RefExample { public static void Main() { diff --git a/snippets/csharp/System/Object/Equals/equals_val1.cs b/snippets/csharp/System/Object/Equals/equals_val1.cs new file mode 100644 index 00000000000..533e01bf098 --- /dev/null +++ b/snippets/csharp/System/Object/Equals/equals_val1.cs @@ -0,0 +1,20 @@ +using System; + +public class Example2 +{ + public static void Main() + { + // + byte value1 = 12; + int value2 = 12; + + object object1 = value1; + object object2 = value2; + + Console.WriteLine($"{object1} ({object1.GetType().Name}) = {object2} ({object2.GetType().Name}): {object1.Equals(object2)}"); + + // The example displays the following output: + // 12 (Byte) = 12 (Int32): False + // + } +} diff --git a/snippets/csharp/System/Object/Equals/equals_val2.cs b/snippets/csharp/System/Object/Equals/equals_val2.cs new file mode 100644 index 00000000000..2c128e53757 --- /dev/null +++ b/snippets/csharp/System/Object/Equals/equals_val2.cs @@ -0,0 +1,40 @@ +// +using System; + +// Define a value type that does not override Equals. +public struct Person3 +{ + private string personName; + + public Person3(string name) + { + this.personName = name; + } + + public override string ToString() + { + return this.personName; + } +} + +public struct Example3 +{ + public static void Main() + { + Person3 person1 = new Person3("John"); + Person3 person2 = new Person3("John"); + + Console.WriteLine("Calling Equals:"); + Console.WriteLine(person1.Equals(person2)); + + Console.WriteLine("\nCasting to an Object and calling Equals:"); + Console.WriteLine(((object) person1).Equals((object) person2)); + } +} +// The example displays the following output: +// Calling Equals: +// True +// +// Casting to an Object and calling Equals: +// True +// diff --git a/snippets/csharp/System/Object/Equals/equalsoverride.cs b/snippets/csharp/System/Object/Equals/equalsoverride.cs new file mode 100644 index 00000000000..b8da28c242f --- /dev/null +++ b/snippets/csharp/System/Object/Equals/equalsoverride.cs @@ -0,0 +1,43 @@ +using System; + +// +public class Person6 +{ + private string idNumber; + private string personName; + + public Person6(string name, string id) + { + this.personName = name; + this.idNumber = id; + } + + public override bool Equals(Object obj) + { + Person6 personObj = obj as Person6; + if (personObj == null) + return false; + else + return idNumber.Equals(personObj.idNumber); + } + + public override int GetHashCode() + { + return this.idNumber.GetHashCode(); + } +} + +public class Example6 +{ + public static void Main() + { + Person6 p1 = new Person6("John", "63412895"); + Person6 p2 = new Person6("Jack", "63412895"); + Console.WriteLine(p1.Equals(p2)); + Console.WriteLine(Object.Equals(p1, p2)); + } +} +// The example displays the following output: +// True +// True +// diff --git a/snippets/csharp/System/Object/Equals/equalssb1.cs b/snippets/csharp/System/Object/Equals/equalssb1.cs new file mode 100644 index 00000000000..b51fd0e2a2a --- /dev/null +++ b/snippets/csharp/System/Object/Equals/equalssb1.cs @@ -0,0 +1,26 @@ +// +using System; +using System.Text; + +public class Example5 +{ + public static void Main() + { + StringBuilder sb1 = new StringBuilder("building a string..."); + StringBuilder sb2 = new StringBuilder("building a string..."); + + Console.WriteLine($"sb1.Equals(sb2): {sb1.Equals(sb2)}"); + Console.WriteLine($"((Object) sb1).Equals(sb2): {((Object) sb1).Equals(sb2)}"); + Console.WriteLine($"Object.Equals(sb1, sb2): {Object.Equals(sb1, sb2)}"); + + Object sb3 = new StringBuilder("building a string..."); + Console.WriteLine($"\nsb3.Equals(sb2): {sb3.Equals(sb2)}"); + } +} +// The example displays the following output: +// sb1.Equals(sb2): True +// ((Object) sb1).Equals(sb2): False +// Object.Equals(sb1, sb2): False +// +// sb3.Equals(sb2): False +// diff --git a/snippets/csharp/System/Object/Finalize/finalize_safe.cs b/snippets/csharp/System/Object/Finalize/finalize_safe.cs new file mode 100644 index 00000000000..3206babdc10 --- /dev/null +++ b/snippets/csharp/System/Object/Finalize/finalize_safe.cs @@ -0,0 +1,172 @@ +// +using Microsoft.Win32.SafeHandles; +using System; +using System.ComponentModel; +using System.IO; +using System.Runtime.InteropServices; + +public class FileAssociationInfo : IDisposable +{ + // Private variables. + private string openCmd; + private string args; + private SafeRegistryHandle hExtHandle, hAppIdHandle; + + // Windows API calls. + [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern int RegOpenKeyEx(IntPtr hKey, + string lpSubKey, int ulOptions, int samDesired, + out IntPtr phkResult); + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueExW", + SetLastError = true)] + private static extern int RegQueryValueEx(IntPtr hKey, + string lpValueName, int lpReserved, out uint lpType, + string lpData, ref uint lpcbData); + [DllImport("advapi32.dll", SetLastError = true)] + private static extern int RegSetValueEx(IntPtr hKey, [MarshalAs(UnmanagedType.LPStr)] string lpValueName, + int Reserved, uint dwType, [MarshalAs(UnmanagedType.LPStr)] string lpData, + int cpData); + [DllImport("advapi32.dll", SetLastError = true)] + private static extern int RegCloseKey(UIntPtr hKey); + + // Windows API constants. + private const int HKEY_CLASSES_ROOT = unchecked((int)0x80000000); + private const int ERROR_SUCCESS = 0; + + private const int KEY_QUERY_VALUE = 1; + private const int KEY_SET_VALUE = 0x2; + + private const uint REG_SZ = 1; + + private const int MAX_PATH = 260; + + public FileAssociationInfo(string fileExtension) + { + if (!fileExtension.StartsWith(".")) + fileExtension = "." + fileExtension; + Extension = fileExtension; + + // Get the file extension value. + int retVal = RegOpenKeyEx(new IntPtr(HKEY_CLASSES_ROOT), fileExtension, 0, KEY_QUERY_VALUE, out IntPtr hExtension); + if (retVal != ERROR_SUCCESS) + throw new Win32Exception(retVal); + // Instantiate the first SafeRegistryHandle. + hExtHandle = new SafeRegistryHandle(hExtension, true); + + string appId = new(' ', MAX_PATH); + uint appIdLength = (uint)appId.Length; + retVal = RegQueryValueEx( + hExtHandle.DangerousGetHandle(), + string.Empty, + 0, + out _, + appId, + ref appIdLength); + if (retVal != ERROR_SUCCESS) + throw new Win32Exception(retVal); + // We no longer need the hExtension handle. + hExtHandle.Dispose(); + + // Determine the number of characters without the terminating null. + appId = appId.Substring(0, (int)appIdLength / 2 - 1) + @"\shell\open\Command"; + + // Open the application identifier key. + string exeName = new(' ', MAX_PATH); + _ = (uint)exeName.Length; + retVal = RegOpenKeyEx( + new IntPtr(HKEY_CLASSES_ROOT), + appId, + 0, + KEY_QUERY_VALUE | KEY_SET_VALUE, + out IntPtr hAppId); + if (retVal != ERROR_SUCCESS) + throw new Win32Exception(retVal); + + // Instantiate the second SafeRegistryHandle. + hAppIdHandle = new SafeRegistryHandle(hAppId, true); + + // Get the executable name for this file type. + string exePath = new(' ', MAX_PATH); + uint exePathLength = (uint)exePath.Length; + retVal = RegQueryValueEx( + hAppIdHandle.DangerousGetHandle(), + string.Empty, + 0, + out _, + exePath, + ref exePathLength); + if (retVal != ERROR_SUCCESS) + throw new Win32Exception(retVal); + + // Determine the number of characters without the terminating null. + exePath = exePath.Substring(0, (int)exePathLength / 2 - 1); + // Remove any environment strings. + exePath = Environment.ExpandEnvironmentVariables(exePath); + + int position = exePath.IndexOf('%'); + if (position >= 0) + { + args = exePath.Substring(position); + // Remove command line parameters ('%0', etc.). + exePath = exePath.Substring(0, position).Trim(); + } + openCmd = exePath; + } + + public string Extension { get; } + + public string Open + { + get { return openCmd; } + set + { + if (hAppIdHandle.IsInvalid | hAppIdHandle.IsClosed) + throw new InvalidOperationException("Cannot write to registry key."); + if (!File.Exists(value)) + { + string message = string.Format("'{0}' does not exist", value); + throw new FileNotFoundException(message); + } + string cmd = value + " %1"; + int retVal = RegSetValueEx( + hAppIdHandle.DangerousGetHandle(), + string.Empty, + 0, + REG_SZ, + cmd, + cmd.Length + 1); + if (retVal != ERROR_SUCCESS) + throw new Win32Exception(retVal); + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + protected void Dispose(bool disposing) + { + // Ordinarily, you release unmanaged resources here, + // but all are wrapped by safe handles. + + // Release disposable objects. + if (disposing) + { + hExtHandle?.Dispose(); + hAppIdHandle?.Dispose(); + } + } +} +// + +public class Example +{ + public static void Main() + { + FileAssociationInfo fa = new(".txt"); + Console.WriteLine($"{fa.Extension} files are handled by '{fa.Open}'"); + fa.Dispose(); + } +} diff --git a/snippets/csharp/System/Object/GetHashCode/Project.csproj b/snippets/csharp/System/Object/GetHashCode/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Object/GetHashCode/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Object/GetHashCode/direct1.cs b/snippets/csharp/System/Object/GetHashCode/direct1.cs new file mode 100644 index 00000000000..666b1dff966 --- /dev/null +++ b/snippets/csharp/System/Object/GetHashCode/direct1.cs @@ -0,0 +1,60 @@ +// +using System; + +public struct Number +{ + private int n; + + public Number(int value) + { + n = value; + } + + public int Value + { + get { return n; } + } + + public override bool Equals(Object obj) + { + if (obj == null || ! (obj is Number)) + return false; + else + return n == ((Number) obj).n; + } + + public override int GetHashCode() + { + return n; + } + + public override string ToString() + { + return n.ToString(); + } +} + +public class Example1 +{ + public static void Main() + { + Random rnd = new Random(); + for (int ctr = 0; ctr <= 9; ctr++) { + int randomN = rnd.Next(Int32.MinValue, Int32.MaxValue); + Number n = new Number(randomN); + Console.WriteLine("n = {0,12}, hash code = {1,12}", n, n.GetHashCode()); + } + } +} +// The example displays output like the following: +// n = -634398368, hash code = -634398368 +// n = 2136747730, hash code = 2136747730 +// n = -1973417279, hash code = -1973417279 +// n = 1101478715, hash code = 1101478715 +// n = 2078057429, hash code = 2078057429 +// n = -334489950, hash code = -334489950 +// n = -68958230, hash code = -68958230 +// n = -379951485, hash code = -379951485 +// n = -31553685, hash code = -31553685 +// n = 2105429592, hash code = 2105429592 +// diff --git a/snippets/csharp/System/Object/GetHashCode/shift1.cs b/snippets/csharp/System/Object/GetHashCode/shift1.cs new file mode 100644 index 00000000000..c9f7c4431f9 --- /dev/null +++ b/snippets/csharp/System/Object/GetHashCode/shift1.cs @@ -0,0 +1,72 @@ +// +using System; + +public struct Point +{ + private int x; + private int y; + + public Point(int x, int y) + { + this.x = x; + this.y = y; + } + + public override bool Equals(Object obj) + { + if (!(obj is Point)) return false; + + Point p = (Point) obj; + return x == p.x & y == p.y; + } + + public override int GetHashCode() + { + return ShiftAndWrap(x.GetHashCode(), 2) ^ y.GetHashCode(); + } + + private int ShiftAndWrap(int value, int positions) + { + positions = positions & 0x1F; + + // Save the existing bit pattern, but interpret it as an unsigned integer. + uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); + // Preserve the bits to be discarded. + uint wrapped = number >> (32 - positions); + // Shift and wrap the discarded bits. + return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0); + } +} + +public class Example2 +{ + public static void Main() + { + Point pt = new Point(5, 8); + Console.WriteLine(pt.GetHashCode()); + + pt = new Point(8, 5); + Console.WriteLine(pt.GetHashCode()); + } +} +// The example displays the following output: +// 28 +// 37 +// + +public class Utility +{ + // + public int ShiftAndWrap(int value, int positions) + { + positions = positions & 0x1F; + + // Save the existing bit pattern, but interpret it as an unsigned integer. + uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); + // Preserve the bits to be discarded. + uint wrapped = number >> (32 - positions); + // Shift and wrap the discarded bits. + return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0); + } + // +} diff --git a/snippets/csharp/System/Object/GetHashCode/xor1.cs b/snippets/csharp/System/Object/GetHashCode/xor1.cs new file mode 100644 index 00000000000..a37b2efa1b4 --- /dev/null +++ b/snippets/csharp/System/Object/GetHashCode/xor1.cs @@ -0,0 +1,44 @@ +// +using System; + +// A type that represents a 2-D point. +public struct Point2 +{ + private int x; + private int y; + + public Point2(int x, int y) + { + this.x = x; + this.y = y; + } + + public override bool Equals(Object obj) + { + if (! (obj is Point2)) return false; + + Point2 p = (Point2) obj; + return x == p.x & y == p.y; + } + + public override int GetHashCode() + { + return x ^ y; + } +} + +public class Example3 +{ + public static void Main() + { + Point2 pt = new Point2(5, 8); + Console.WriteLine(pt.GetHashCode()); + + pt = new Point2(8, 5); + Console.WriteLine(pt.GetHashCode()); + } +} +// The example displays the following output: +// 13 +// 13 +// diff --git a/snippets/csharp/System/Object/GetHashCode/xor2.cs b/snippets/csharp/System/Object/GetHashCode/xor2.cs new file mode 100644 index 00000000000..d8ad45dd2f9 --- /dev/null +++ b/snippets/csharp/System/Object/GetHashCode/xor2.cs @@ -0,0 +1,49 @@ +// +using System; + +public struct Point3 +{ + private int x; + private int y; + + public Point3(int x, int y) + { + this.x = x; + this.y = y; + } + + public override bool Equals(Object obj) + { + if (obj is Point3) + { + Point3 p = (Point3) obj; + return x == p.x & y == p.y; + } + else + { + return false; + } + } + + public override int GetHashCode() + { + return HashCode.Combine(x, y); + } +} + +public class Example +{ + public static void Main() + { + Point3 pt = new Point3(5, 8); + Console.WriteLine(pt.GetHashCode()); + + pt = new Point3(8, 5); + Console.WriteLine(pt.GetHashCode()); + } +} +// The example displays output similar to the following. +// Note: HashCode.Combine results are not stable across .NET versions. +// 185727722 +// -363254492 +// diff --git a/snippets/csharp/System/Object/ToString/Project.csproj b/snippets/csharp/System/Object/ToString/Project.csproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/csharp/System/Object/ToString/Project.csproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/csharp/System/Object/ToString/array1.cs b/snippets/csharp/System/Object/ToString/array1.cs new file mode 100644 index 00000000000..cf7b237be0c --- /dev/null +++ b/snippets/csharp/System/Object/ToString/array1.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +public class Example +{ + public static void Main() + { + // + int[] values = { 1, 2, 4, 8, 16, 32, 64, 128 }; + Console.WriteLine(values.ToString()); + + List list = new List(values); + Console.WriteLine(list.ToString()); + + // The example displays the following output: + // System.Int32[] + // System.Collections.Generic.List`1[System.Int32] + // + } +} diff --git a/snippets/csharp/System/Object/ToString/customize1.cs b/snippets/csharp/System/Object/ToString/customize1.cs new file mode 100644 index 00000000000..6a8593a7b6c --- /dev/null +++ b/snippets/csharp/System/Object/ToString/customize1.cs @@ -0,0 +1,38 @@ +// +using System; +using System.Collections.Generic; + +public class CList : List +{ + public CList(IEnumerable collection) : base(collection) + { } + + public CList() : base() + {} + + public override string ToString() + { + string retVal = string.Empty; + foreach (T item in this) { + if (string.IsNullOrEmpty(retVal)) + retVal += item.ToString(); + else + retVal += string.Format(", {0}", item); + } + return retVal; + } +} + +public class Example2 +{ + public static void Main() + { + var list2 = new CList(); + list2.Add(1000); + list2.Add(2000); + Console.WriteLine(list2.ToString()); + } +} +// The example displays the following output: +// 1000, 2000 +// diff --git a/snippets/csharp/System/Object/ToString/customize2.cs b/snippets/csharp/System/Object/ToString/customize2.cs new file mode 100644 index 00000000000..bc7495d7690 --- /dev/null +++ b/snippets/csharp/System/Object/ToString/customize2.cs @@ -0,0 +1,47 @@ +// +using System; +using System.Collections.Generic; + +public static class StringExtensions +{ + public static string ToString2(this List l) + { + string retVal = string.Empty; + foreach (T item in l) + retVal += string.Format("{0}{1}", string.IsNullOrEmpty(retVal) ? + "" : ", ", + item); + return string.IsNullOrEmpty(retVal) ? "{}" : "{ " + retVal + " }"; + } + + public static string ToString(this List l, string fmt) + { + string retVal = string.Empty; + foreach (T item in l) { + IFormattable ifmt = item as IFormattable; + if (ifmt != null) + retVal += string.Format("{0}{1}", + string.IsNullOrEmpty(retVal) ? + "" : ", ", ifmt.ToString(fmt, null)); + else + retVal += ToString2(l); + } + return string.IsNullOrEmpty(retVal) ? "{}" : "{ " + retVal + " }"; + } +} + +public class Example3 +{ + public static void Main() + { + List list = new List(); + list.Add(1000); + list.Add(2000); + Console.WriteLine(list.ToString2()); + Console.WriteLine(list.ToString("N0")); + } +} +// The example displays the following output: +// { 1000, 2000 } +// { 1,000, 2,000 } +// diff --git a/snippets/csharp/System/Object/ToString/tostring1.cs b/snippets/csharp/System/Object/ToString/tostring1.cs new file mode 100644 index 00000000000..4651e461af2 --- /dev/null +++ b/snippets/csharp/System/Object/ToString/tostring1.cs @@ -0,0 +1,15 @@ +using System; + +public class Example4 +{ + public static void Main() + { + // + Object obj = new Object(); + Console.WriteLine(obj.ToString()); + + // The example displays the following output: + // System.Object + // + } +} diff --git a/snippets/csharp/System/Object/ToString/tostring2.cs b/snippets/csharp/System/Object/ToString/tostring2.cs new file mode 100644 index 00000000000..651cd69732c --- /dev/null +++ b/snippets/csharp/System/Object/ToString/tostring2.cs @@ -0,0 +1,22 @@ +// +using System; +using Examples; + +namespace Examples +{ + public class Object1 + { + } +} + +public class Example5 +{ + public static void Main() + { + object obj1 = new Object1(); + Console.WriteLine(obj1.ToString()); + } +} +// The example displays the following output: +// Examples.Object1 +// diff --git a/snippets/csharp/System/Object/ToString/tostring3.cs b/snippets/csharp/System/Object/ToString/tostring3.cs new file mode 100644 index 00000000000..8752cac0b47 --- /dev/null +++ b/snippets/csharp/System/Object/ToString/tostring3.cs @@ -0,0 +1,29 @@ +// +using System; + +public class Object2 +{ + private object value; + + public Object2(object value) + { + this.value = value; + } + + public override string ToString() + { + return base.ToString() + ": " + value.ToString(); + } +} + +public class Example6 +{ + public static void Main() + { + Object2 obj2 = new Object2('a'); + Console.WriteLine(obj2.ToString()); + } +} +// The example displays the following output: +// Object2: a +// diff --git a/snippets/csharp/System/Object/ToString/tostringoverload1.cs b/snippets/csharp/System/Object/ToString/tostringoverload1.cs new file mode 100644 index 00000000000..83cf6df70ad --- /dev/null +++ b/snippets/csharp/System/Object/ToString/tostringoverload1.cs @@ -0,0 +1,75 @@ +// +using System; + +public class Automobile +{ + private int _doors; + private string _cylinders; + private int _year; + private string _model; + + public Automobile(string model, int year , int doors, + string cylinders) + { + _model = model; + _year = year; + _doors = doors; + _cylinders = cylinders; + } + + public int Doors + { get { return _doors; } } + + public string Model + { get { return _model; } } + + public int Year + { get { return _year; } } + + public string Cylinders + { get { return _cylinders; } } + + public override string ToString() + { + return ToString("G"); + } + + public string ToString(string fmt) + { + if (string.IsNullOrEmpty(fmt)) + fmt = "G"; + + switch (fmt.ToUpperInvariant()) + { + case "G": + return string.Format("{0} {1}", _year, _model); + case "D": + return string.Format("{0} {1}, {2} dr.", + _year, _model, _doors); + case "C": + return string.Format("{0} {1}, {2}", + _year, _model, _cylinders); + case "A": + return string.Format("{0} {1}, {2} dr. {3}", + _year, _model, _doors, _cylinders); + default: + string msg = string.Format("'{0}' is an invalid format string", + fmt); + throw new ArgumentException(msg); + } + } +} + +public class Example7 +{ + public static void Main() + { + var auto = new Automobile("Lynx", 2016, 4, "V8"); + Console.WriteLine(auto.ToString()); + Console.WriteLine(auto.ToString("A")); + } +} +// The example displays the following output: +// 2016 Lynx +// 2016 Lynx, 4 dr. V8 +// diff --git a/snippets/csharp/System/Object/ToString/tostringoverload2.cs b/snippets/csharp/System/Object/ToString/tostringoverload2.cs new file mode 100644 index 00000000000..cce98befd3e --- /dev/null +++ b/snippets/csharp/System/Object/ToString/tostringoverload2.cs @@ -0,0 +1,24 @@ +// +using System; +using System.Globalization; + +public class Example8 +{ + public static void Main() + { + string[] cultureNames = { "en-US", "en-GB", "fr-FR", + "hr-HR", "ja-JP" }; + Decimal value = 1603.49m; + foreach (var cultureName in cultureNames) { + CultureInfo culture = new CultureInfo(cultureName); + Console.WriteLine($"{culture.Name}: {value.ToString("C2", culture)}"); + } + } +} +// The example displays the following output: +// en-US: $1,603.49 +// en-GB: £1,603.49 +// fr-FR: 1 603,49 € +// hr-HR: 1.603,49 kn +// ja-JP: ¥1,603.49 +// diff --git a/snippets/fsharp/System/Convert/ToInt64/formatting1.fs b/snippets/fsharp/System/Convert/ToInt64/formatting1.fs new file mode 100644 index 00000000000..b6fe8ddd305 --- /dev/null +++ b/snippets/fsharp/System/Convert/ToInt64/formatting1.fs @@ -0,0 +1,53 @@ +open System + +let callToString () = + // + let numbers = [| -1403L; 0L; 169L; 1483104L |] + for number in numbers do + // Display value using default formatting. + printf $"{number.ToString(),-8} --> " + // Display value with 3 digits and leading zeros. + printf $"{number,8:D3}" + // Display value with 1 decimal digit. + printf $"{number,13:N1}" + // Display value as hexadecimal. + printf $"{number,18:X2}" + // Display value with eight hexadecimal digits. + printfn $"{number,18:X8}" + + // The example displays the following output: + // -1403 --> -1403 -1,403.0 FFFFFFFFFFFFFA85 FFFFFFFFFFFFFA85 + // 0 --> 000 0.0 00 00000000 + // 169 --> 169 169.0 A9 000000A9 + // 1483104 --> 1483104 1,483,104.0 16A160 0016A160 + // + +let callConvert () = + // + let numbers = [| -146L; 11043L; 2781913L |] + for number in numbers do + printfn $"{number} (Base 10):" + printfn $" Binary: {Convert.ToString(number, 2)}" + printfn $" Octal: {Convert.ToString(number, 8)}" + printfn $" Hex: {Convert.ToString(number, 16)}\n" + + // The example displays the following output: + // -146 (Base 10): + // Binary: 1111111111111111111111111111111111111111111111111111111101101110 + // Octal: 1777777777777777777556 + // Hex: ffffffffffffff6e + // + // 11043 (Base 10): + // Binary: 10101100100011 + // Octal: 25443 + // Hex: 2b23 + // + // 2781913 (Base 10): + // Binary: 1010100111001011011001 + // Octal: 12471331 + // Hex: 2a72d9 + // + +callToString () +printfn "-----" +callConvert () diff --git a/snippets/fsharp/System/Int32/Overview/Formatting1.fs b/snippets/fsharp/System/Int32/Overview/Formatting1.fs new file mode 100644 index 00000000000..8655954ddb0 --- /dev/null +++ b/snippets/fsharp/System/Int32/Overview/Formatting1.fs @@ -0,0 +1,43 @@ +open System + +let callToString () = + // + let numbers = [| -1403; 0; 169; 1483104 |] + for number in numbers do + // Display value using default formatting. + printf $"{number,-8} --> " + // Display value with 3 digits and leading zeros. + printf $"{number,11:D3}" + // Display value with 1 decimal digit. + printf $"{number,13:N1}" + // Display value as hexadecimal. + printf $"{number,12:X2}" + // Display value with eight hexadecimal digits. + printfn $"{number,14:X8}" + + + // The example displays the following output: + // -1403 --> -1403 -1,403.0 FFFFFA85 FFFFFA85 + // 0 --> 000 0.0 00 00000000 + // 169 --> 169 169.0 A9 000000A9 + // 1483104 --> 1483104 1,483,104.0 16A160 0016A160 + // + + +let callConvert () = + // + let numbers = [| -146; 11043; 2781913 |] + printfn $"""{"Value",8} {"Binary",32} {"Octal",11} {"Hex",10}""" + for number in numbers do + printfn $"{number,8} {Convert.ToString(number, 2),32} {Convert.ToString(number, 8),11} {Convert.ToString(number, 16),10}" + + // The example displays the following output: + // Value Binary Octal Hex + // -146 11111111111111111111111101101110 37777777556 ffffff6e + // 11043 10101100100011 25443 2b23 + // 2781913 1010100111001011011001 12471331 2a72d9 + // + +callToString () +printfn "-----" +callConvert () diff --git a/snippets/fsharp/System/Int32/Overview/Instantiate1.fs b/snippets/fsharp/System/Int32/Overview/Instantiate1.fs new file mode 100644 index 00000000000..b572762c657 --- /dev/null +++ b/snippets/fsharp/System/Int32/Overview/Instantiate1.fs @@ -0,0 +1,83 @@ +open System +open System.Numerics + +let instantiateByAssignment () = + // + let number1 = 64301 + let number2 = 25548612 + // + printfn $"{number1} - {number2}" + +let instantiateByNarrowingConversion () = + // + let lNumber = 163245617L + try + let number1 = int lNumber + printfn $"{number1}" + with :? OverflowException -> + printfn $"{lNumber} is out of range of an Int32." + + let dbl2 = 35901.997 + try + let number2 = int dbl2 + printfn $"{number2}" + with :? OverflowException -> + printfn $"{dbl2} is out of range of an Int32." + + let bigNumber = BigInteger 132451 + try + let number3 = int bigNumber + printfn $"{number3}" + with :? OverflowException -> + printfn $"{bigNumber} is out of range of an Int32." + + // The example displays the following output: + // 163245617 + // 35902 + // 132451 + // + +let parse () = + // + let string1 = "244681" + try + let number1 = Int32.Parse string1 + printfn $"{number1}" + with + | :? OverflowException -> + printfn $"'{string1}' is out of range of a 32-bit integer." + | :? FormatException -> + printfn $"The format of '{string1}' is invalid." + + let string2 = "F9A3C" + try + let number2 = Int32.Parse(string2, System.Globalization.NumberStyles.HexNumber) + printfn $"{number2}" + with + | :? OverflowException -> + printfn $"'{string2}' is out of range of a 32-bit integer." + | :? FormatException -> + printfn $"The format of '{string2}' is invalid." + + // The example displays the following output: + // 244681 + // 1022524 + // + +let instantiateByWideningConversion () = + // + let value1 = 124y + let value2 = 1618s + + let number1 = int value1 + let number2 = int value2 + // + () + +instantiateByAssignment () +printfn "----" +instantiateByNarrowingConversion () +printfn "----" +parse () +printfn "----" +instantiateByWideningConversion () diff --git a/snippets/fsharp/System/Int32/Overview/toint32_1.fs b/snippets/fsharp/System/Int32/Overview/toint32_1.fs new file mode 100644 index 00000000000..68d15b28a09 --- /dev/null +++ b/snippets/fsharp/System/Int32/Overview/toint32_1.fs @@ -0,0 +1,25 @@ +open System + +// +let values = + [| Decimal.MinValue; -1034.23M; -12m; 0M; 147M + 199.55M; 9214.16M; Decimal.MaxValue |] + +for value in values do + try + let result = Convert.ToInt32 value + printfn $"Converted the {value.GetType().Name} value '{value}' to the {result.GetType().Name} value {result}." + + with :? OverflowException -> + printfn $"{value} is outside the range of the Int32 type." + +// 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. +// \ No newline at end of file diff --git a/snippets/fsharp/System/Int64/Overview/instantiate1.fs b/snippets/fsharp/System/Int64/Overview/instantiate1.fs new file mode 100644 index 00000000000..6d2644a4a7f --- /dev/null +++ b/snippets/fsharp/System/Int64/Overview/instantiate1.fs @@ -0,0 +1,89 @@ +open System +open System.Globalization +open System.Numerics + +let instantiateByAssignment () = + // + let number1 = -64301728L + let number2 = 255486129307L + // + printfn $"{number1} - {number2}" + + +let instantiateByNarrowingConversion () = + // + let ulNumber = 163245617943825uL + try + let number1 = int64 ulNumber + printfn $"{number1}" + with :? OverflowException -> + printfn $"{ulNumber} is out of range of an Int64." + + let dbl2 = 35901.997 + try + let number2 = int64 dbl2 + printfn $"{number2}" + with :? OverflowException -> + printfn $"{dbl2} is out of range of an Int64." + + let bigNumber = BigInteger 1.63201978555e30 + try + let number3 = int64 bigNumber + printfn $"{number3}" + with :? OverflowException -> + printfn $"{bigNumber} is out of range of an Int64." + + // The example displays the following output: + // 163245617943825 + // 35902 + // 1,632,019,785,549,999,969,612,091,883,520 is out of range of an Int64. + // + +let parse () = + // + let string1 = "244681903147" + try + let number1 = Int64.Parse string1 + printfn $"{number1}" + with + | :? OverflowException -> + printfn $"'{string1}' is out of range of a 64-bit integer." + | :? FormatException -> + printfn $"The format of '{string1}' is invalid." + + let string2 = "F9A3CFF0A" + try + let number2 = Int64.Parse(string2, NumberStyles.HexNumber) + printfn $"{number2}" + + with + | :? OverflowException -> + printfn $"'{string2}' is out of range of a 64-bit integer." + | :? FormatException -> + printfn $"The format of '{string2}' is invalid." + + // The example displays the following output: + // 244681903147 + // 67012198154 + // + +let instantiateByWideningConversion () = + // + let value1 = 124y + let value2 = 1618s + let value3 = Int32.MaxValue + + let number1 = int64 value1 + let number2 = int64 value2 + let number3: int64 = value3 + // + () + + +instantiateByAssignment () +printfn "----" +instantiateByNarrowingConversion () +printfn "----" +parse () +printfn "----" +instantiateByWideningConversion () \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Equals/equals2.fs b/snippets/fsharp/System/Object/Equals/equals2.fs new file mode 100644 index 00000000000..4724fd1968c --- /dev/null +++ b/snippets/fsharp/System/Object/Equals/equals2.fs @@ -0,0 +1,54 @@ +module equals2 + +// +type Point(x, y) = + new () = Point(0, 0) + member _.X = x + member _.Y = y + + override _.Equals(obj) = + //Check for null and compare run-time types. + match obj with + | :? Point as p -> + x = p.X && y = p.Y + | _ -> + false + + override _.GetHashCode() = + System.HashCode.Combine(x, y) + + override _.ToString() = + $"Point({x}, {y})" + +type Point3D(x, y, z) = + inherit Point(x, y) + member _.Z = z + + override _.Equals(obj) = + match obj with + | :? Point3D as pt3 -> + base.Equals(pt3 :> Point) && z = pt3.Z + | _ -> + false + + override _.GetHashCode() = + System.HashCode.Combine(base.GetHashCode(), z) + + override _.ToString() = + $"Point({x}, {y}, {z})" + +let point2D = Point(5, 5) +let point3Da = Point3D(5, 5, 2) +let point3Db = Point3D(5, 5, 2) +let point3Dc = Point3D(5, 5, -1) + +printfn $"{point2D} = {point3Da}: {point2D.Equals point3Da}" +printfn $"{point2D} = {point3Db}: {point2D.Equals point3Db}" +printfn $"{point3Da} = {point3Db}: {point3Da.Equals point3Db}" +printfn $"{point3Da} = {point3Dc}: {point3Da.Equals point3Dc}" +// The example displays the following output: +// Point(5, 5) = Point(5, 5, 2): False +// Point(5, 5) = Point(5, 5, 2): False +// Point(5, 5, 2) = Point(5, 5, 2): True +// Point(5, 5, 2) = Point(5, 5, -1): False +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Equals/equals3.fs b/snippets/fsharp/System/Object/Equals/equals3.fs new file mode 100644 index 00000000000..4321df320d4 --- /dev/null +++ b/snippets/fsharp/System/Object/Equals/equals3.fs @@ -0,0 +1,51 @@ +module equals3 + +// +type Point(x, y) = + member _.X = x + member _.Y = y + + override _.Equals(obj) = + // Performs an equality check on two points (integer pairs). + match obj with + | :? Point as p -> + x = p.X && y = p.Y + | _ -> + false + + override _.GetHashCode() = + (x, y).GetHashCode() + +type Rectangle(upLeftX, upLeftY, downRightX, downRightY) = + let a = Point(upLeftX, upLeftY) + let b = Point(downRightX, downRightY) + + member _.UpLeft = a + member _.DownRight = b + + override _.Equals(obj) = + // Perform an equality check on two rectangles (Point object pairs). + match obj with + | :? Rectangle as r -> + a.Equals(r.UpLeft) && b.Equals(r.DownRight) + | _ -> + false + + override _.GetHashCode() = + (a, b).GetHashCode() + + override _.ToString() = + $"Rectangle({a.X}, {a.Y}, {b.X}, {b.Y})" + +let r1 = Rectangle(0, 0, 100, 200) +let r2 = Rectangle(0, 0, 100, 200) +let r3 = Rectangle(0, 0, 150, 200) + +printfn $"{r1} = {r2}: {r1.Equals r2}" +printfn $"{r1} = {r3}: {r1.Equals r3}" +printfn $"{r2} = {r3}: {r2.Equals r3}" +// The example displays the following output: +// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 100, 200): True +// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False +// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Equals/equals4.fs b/snippets/fsharp/System/Object/Equals/equals4.fs new file mode 100644 index 00000000000..ecde006fa16 --- /dev/null +++ b/snippets/fsharp/System/Object/Equals/equals4.fs @@ -0,0 +1,48 @@ +module equals4 + +// +[] +type Complex = + val mutable re: double + val mutable im: double + + override this.Equals(obj) = + match obj with + | :? Complex as c when c = this -> true + | _ -> false + + override this.GetHashCode() = + (this.re, this.im).GetHashCode() + + override this.ToString() = + $"({this.re}, {this.im})" + + static member op_Equality (x: Complex, y: Complex) = + x.re = y.re && x.im = y.im + + static member op_Inequality (x: Complex, y: Complex) = + x = y |> not + +let mutable cmplx1 = Complex() +let mutable cmplx2 = Complex() + +cmplx1.re <- 4.0 +cmplx1.im <- 1.0 + +cmplx2.re <- 2.0 +cmplx2.im <- 1.0 + +printfn $"{cmplx1} <> {cmplx2}: {cmplx1 <> cmplx2}" +printfn $"{cmplx1} = {cmplx2}: {cmplx1.Equals cmplx2}" + +cmplx2.re <- 4.0 + +printfn $"{cmplx1} = {cmplx2}: {cmplx1 = cmplx2}" +printfn $"{cmplx1} = {cmplx2}: {cmplx1.Equals cmplx2}" + +// The example displays the following output: +// (4, 1) <> (2, 1): True +// (4, 1) = (2, 1): False +// (4, 1) = (4, 1): True +// (4, 1) = (4, 1): True +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Equals/equals_ref.fs b/snippets/fsharp/System/Object/Equals/equals_ref.fs new file mode 100644 index 00000000000..230ddffa411 --- /dev/null +++ b/snippets/fsharp/System/Object/Equals/equals_ref.fs @@ -0,0 +1,27 @@ +module equals_ref + +// +// Define a reference type that does not override Equals. +type Person(name) = + override _.ToString() = + name + +let person1a = Person "John" +let person1b = person1a +let person2 = Person(string person1a) + +printfn "Calling Equals:" +printfn $"person1a and person1b: {person1a.Equals person1b}" +printfn $"person1a and person2: {person1a.Equals person2}" + +printfn "\nCasting to an Object and calling Equals:" +printfn $"person1a and person1b: {(person1a :> obj).Equals(person1b :> obj)}" +printfn $"person1a and person2: {(person1a :> obj).Equals(person2 :> obj)}" +// The example displays the following output: +// person1a and person1b: True +// person1a and person2: False +// +// Casting to an Object and calling Equals: +// person1a and person1b: True +// person1a and person2: False +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Equals/equals_val1.fs b/snippets/fsharp/System/Object/Equals/equals_val1.fs new file mode 100644 index 00000000000..1a3807394a7 --- /dev/null +++ b/snippets/fsharp/System/Object/Equals/equals_val1.fs @@ -0,0 +1,14 @@ +module equals_val1 + +// +let value1 = 12uy +let value2 = 12 + +let object1 = value1 :> obj +let object2 = value2 :> obj + +printfn $"{object1} ({object1.GetType().Name}) = {object2} ({object2.GetType().Name}): {object1.Equals object2}" + +// The example displays the following output: +// 12 (Byte) = 12 (Int32): False +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Equals/equals_val2.fs b/snippets/fsharp/System/Object/Equals/equals_val2.fs new file mode 100644 index 00000000000..c41c65f0bb0 --- /dev/null +++ b/snippets/fsharp/System/Object/Equals/equals_val2.fs @@ -0,0 +1,24 @@ +module equals_val2 + +// +// Define a value type that does not override Equals. +[] +type Person(personName: string) = + override _.ToString() = + personName + +let person1 = Person "John" +let person2 = Person "John" + +printfn "Calling Equals:" +printfn $"{person1.Equals person2}" + +printfn $"\nCasting to an Object and calling Equals:" +printfn $"{(person1 :> obj).Equals(person2 :> obj)}" +// The example displays the following output: +// Calling Equals: +// True +// +// Casting to an Object and calling Equals: +// True +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Equals/equalsoverride.fs b/snippets/fsharp/System/Object/Equals/equalsoverride.fs new file mode 100644 index 00000000000..bf1d13a6fa8 --- /dev/null +++ b/snippets/fsharp/System/Object/Equals/equalsoverride.fs @@ -0,0 +1,27 @@ +module equalsoverride + +// +open System + +type Person(name, id) = + member _.Name = name + member _.Id = id + + override _.Equals(obj) = + match obj with + | :? Person as personObj -> + id.Equals personObj.Id + | _ -> + false + + override _.GetHashCode() = + id.GetHashCode() + +let p1 = Person("John", "63412895") +let p2 = Person("Jack", "63412895") +printfn $"{p1.Equals p2}" +printfn $"{Object.Equals(p1, p2)}" +// The example displays the following output: +// True +// True +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Equals/equalssb1.fs b/snippets/fsharp/System/Object/Equals/equalssb1.fs new file mode 100644 index 00000000000..632f5045d98 --- /dev/null +++ b/snippets/fsharp/System/Object/Equals/equalssb1.fs @@ -0,0 +1,23 @@ +module equalssb1 + +// +open System +open System.Text + +let sb1 = StringBuilder "building a string..." +let sb2 = StringBuilder "building a string..." + +printfn $"sb1.Equals(sb2): {sb1.Equals sb2}" +printfn $"((Object) sb1).Equals(sb2): {(sb1 :> obj).Equals sb2}" + +printfn $"Object.Equals(sb1, sb2): {Object.Equals(sb1, sb2)}" + +let sb3 = StringBuilder "building a string..." +printfn $"\nsb3.Equals(sb2): {sb3.Equals sb2}" +// The example displays the following output: +// sb1.Equals(sb2): True +// ((Object) sb1).Equals(sb2): False +// Object.Equals(sb1, sb2): False +// +// sb3.Equals(sb2): False +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/Finalize/finalize_safe.fs b/snippets/fsharp/System/Object/Finalize/finalize_safe.fs new file mode 100644 index 00000000000..7004c95cfc0 --- /dev/null +++ b/snippets/fsharp/System/Object/Finalize/finalize_safe.fs @@ -0,0 +1,123 @@ +module finalize_safe + +// +open Microsoft.Win32.SafeHandles +open System +open System.ComponentModel +open System.IO +open System.Runtime.InteropServices + +// Windows API constants. +let HKEY_CLASSES_ROOT = 0x80000000 +let ERROR_SUCCESS = 0 +let KEY_QUERY_VALUE = 1 +let KEY_SET_VALUE = 0x2 +let REG_SZ = 1u +let MAX_PATH = 260 + +// Windows API calls. +[] +extern int RegOpenKeyEx(nativeint hKey, string lpSubKey, int ulOptions, int samDesired, nativeint& phkResult) +[] +extern int RegQueryValueEx(nativeint hKey, string lpValueName, int lpReserved, uint& lpType, string lpData, uint& lpcbData) +[] +extern int RegSetValueEx(nativeint hKey, [] string lpValueName, int Reserved, uint dwType, [] string lpData, int cpData) +[] +extern int RegCloseKey(unativeint hKey) + +type FileAssociationInfo(fileExtension: string) = + // Private values. + let ext = + if fileExtension.StartsWith "." |> not then + "." + fileExtension + else + fileExtension + let mutable args = "" + let mutable hAppIdHandle = Unchecked.defaultof + let mutable hExtHandle = Unchecked.defaultof + let openCmd = + let mutable lpType = 0u + let mutable hExtension = 0n + // Get the file extension value. + let retVal = RegOpenKeyEx(nativeint HKEY_CLASSES_ROOT, fileExtension, 0, KEY_QUERY_VALUE, &hExtension) + if retVal <> ERROR_SUCCESS then + raise (Win32Exception retVal) + // Instantiate the first SafeRegistryHandle. + hExtHandle <- new SafeRegistryHandle(hExtension, true) + + let appId = String(' ', MAX_PATH) + let mutable appIdLength = uint appId.Length + let retVal = RegQueryValueEx(hExtHandle.DangerousGetHandle(), String.Empty, 0, &lpType, appId, &appIdLength) + if retVal <> ERROR_SUCCESS then + raise (Win32Exception retVal) + // We no longer need the hExtension handle. + hExtHandle.Dispose() + + // Determine the number of characters without the terminating null. + let appId = appId.Substring(0, int appIdLength / 2 - 1) + @"\shell\open\Command" + + // Open the application identifier key. + let exeName = String(' ', MAX_PATH) + let exeNameLength = uint exeName.Length + let mutable hAppId = 0n + let retVal = RegOpenKeyEx(nativeint HKEY_CLASSES_ROOT, appId, 0, KEY_QUERY_VALUE ||| KEY_SET_VALUE, &hAppId) + if retVal <> ERROR_SUCCESS then + raise (Win32Exception retVal) + + // Instantiate the second SafeRegistryHandle. + hAppIdHandle <- new SafeRegistryHandle(hAppId, true) + + // Get the executable name for this file type. + let exePath = String(' ', MAX_PATH) + let mutable exePathLength = uint exePath.Length + let retVal = RegQueryValueEx(hAppIdHandle.DangerousGetHandle(), String.Empty, 0, &lpType, exePath, &exePathLength) + if retVal <> ERROR_SUCCESS then + raise (Win32Exception retVal) + + // Determine the number of characters without the terminating null. + let exePath = + exePath.Substring(0, int exePathLength / 2 - 1) + // Remove any environment strings. + |> Environment.ExpandEnvironmentVariables + + let position = exePath.IndexOf '%' + if position >= 0 then + args <- exePath.Substring position + // Remove command line parameters ('%0', etc.). + exePath.Substring(0, position).Trim() + else + exePath + + member _.Extension = + ext + + member _.Open + with get () = openCmd + and set (value) = + if hAppIdHandle.IsInvalid || hAppIdHandle.IsClosed then + raise (InvalidOperationException "Cannot write to registry key.") + if not (File.Exists value) then + raise (FileNotFoundException $"'{value}' does not exist") + + let cmd = value + " %1" + let retVal = RegSetValueEx(hAppIdHandle.DangerousGetHandle(), String.Empty, 0, REG_SZ, cmd, cmd.Length + 1) + if retVal <> ERROR_SUCCESS then + raise (Win32Exception retVal) + + member this.Dispose() = + this.Dispose true + GC.SuppressFinalize this + + member _.Dispose(disposing) = + // Ordinarily, you release unmanaged resources here, + // but all are wrapped by safe handles. + + // Release disposable objects. + if disposing then + if hExtHandle <> null then hExtHandle.Dispose() + if hAppIdHandle <> null then hAppIdHandle.Dispose() + + interface IDisposable with + member this.Dispose() = + this.Dispose() +// diff --git a/snippets/fsharp/System/Object/GetHashCode/fs.fsproj b/snippets/fsharp/System/Object/GetHashCode/Project.fsproj similarity index 71% rename from snippets/fsharp/System/Object/GetHashCode/fs.fsproj rename to snippets/fsharp/System/Object/GetHashCode/Project.fsproj index 6536eab40cf..77f3e54624c 100644 --- a/snippets/fsharp/System/Object/GetHashCode/fs.fsproj +++ b/snippets/fsharp/System/Object/GetHashCode/Project.fsproj @@ -1,13 +1,15 @@ + - Exe - net6.0 + Library + net10.0 + - - \ No newline at end of file + + diff --git a/snippets/fsharp/System/Object/GetHashCode/direct1.fs b/snippets/fsharp/System/Object/GetHashCode/direct1.fs new file mode 100644 index 00000000000..49f21a4c4c2 --- /dev/null +++ b/snippets/fsharp/System/Object/GetHashCode/direct1.fs @@ -0,0 +1,38 @@ +module direct1 + +// +open System + +[] +type Number(value: int) = + member _.Value = value + + override _.Equals(obj) = + match obj with + | :? Number as n -> + n.Value = value + | _ -> false + + override _.GetHashCode() = + value + + override _.ToString() = + string value + +let rnd = Random() +for _ = 0 to 9 do + let randomN = rnd.Next(Int32.MinValue, Int32.MaxValue) + let n = Number randomN + printfn $"n = {n,12}, hash code = {n.GetHashCode(),12}" +// The example displays output like the following: +// n = -634398368, hash code = -634398368 +// n = 2136747730, hash code = 2136747730 +// n = -1973417279, hash code = -1973417279 +// n = 1101478715, hash code = 1101478715 +// n = 2078057429, hash code = 2078057429 +// n = -334489950, hash code = -334489950 +// n = -68958230, hash code = -68958230 +// n = -379951485, hash code = -379951485 +// n = -31553685, hash code = -31553685 +// n = 2105429592, hash code = 2105429592 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/GetHashCode/shift1.fs b/snippets/fsharp/System/Object/GetHashCode/shift1.fs new file mode 100644 index 00000000000..76c44fe52a7 --- /dev/null +++ b/snippets/fsharp/System/Object/GetHashCode/shift1.fs @@ -0,0 +1,50 @@ +module shift1 + +// +open System + +[] +type Point(x: int, y: int) = + member _.X = x + member _.Y = y + override _.Equals(obj) = + match obj with + | :? Point as p -> + x = p.X && y = p.Y + | _ -> + false + + override this.GetHashCode() = + this.ShiftAndWrap(x.GetHashCode(), 2) ^^^ y.GetHashCode() + + member _.ShiftAndWrap(value, positions) = + let positions = positions &&& 0x1F + + // Save the existing bit pattern, but interpret it as an unsigned integer. + let number = BitConverter.ToUInt32(BitConverter.GetBytes value, 0) + // Preserve the bits to be discarded. + let wrapped = number >>> (32 - positions) + // Shift and wrap the discarded bits. + BitConverter.ToInt32(BitConverter.GetBytes((number <<< positions) ||| wrapped), 0) + +let pt = Point(5, 8) +printfn $"{pt.GetHashCode()}" + +let pt2 = Point(8, 5) +printfn $"{pt2.GetHashCode()}" +// The example displays the following output: +// 28 +// 37 +// + +// +let shiftAndWrap (value: int) positions = + let positions = positions &&& 0x1F + + // Save the existing bit pattern, but interpret it as an unsigned integer. + let number = BitConverter.ToUInt32(BitConverter.GetBytes value, 0) + // Preserve the bits to be discarded. + let wrapped = number >>> (32 - positions) + // Shift and wrap the discarded bits. + BitConverter.ToInt32(BitConverter.GetBytes((number <<< positions) ||| wrapped), 0) +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/GetHashCode/xor1.fs b/snippets/fsharp/System/Object/GetHashCode/xor1.fs new file mode 100644 index 00000000000..54e341a1f7a --- /dev/null +++ b/snippets/fsharp/System/Object/GetHashCode/xor1.fs @@ -0,0 +1,29 @@ +module xor1 + +// +// A type that represents a 2-D point. +[] +type Point(x: int, y: int) = + member _.X = x + member _.Y = y + + override _.Equals(obj) = + match obj with + | :? Point as p -> + x = p.X && y = p.Y + | _ -> + false + + override _.GetHashCode() = + x ^^^ y + +let pt = Point(5, 8) +printfn $"{pt.GetHashCode()}" + +let pt2 = Point(8, 5) +printfn $"{pt2.GetHashCode()}" + +// The example displays the following output: +// 13 +// 13 +// diff --git a/snippets/fsharp/System/Object/GetHashCode/xor2.fs b/snippets/fsharp/System/Object/GetHashCode/xor2.fs new file mode 100644 index 00000000000..1290f982eb0 --- /dev/null +++ b/snippets/fsharp/System/Object/GetHashCode/xor2.fs @@ -0,0 +1,28 @@ +module xor2 + +// +[] +type Point(x: int, y: int) = + member _.X = x + member _.Y = y + + override _.Equals(obj) = + match obj with + | :? Point as p -> + x = p.X && y = p.Y + | _ -> + false + + override _.GetHashCode() = + System.HashCode.Combine(x, y) + +let pt = Point(5, 8) +printfn $"{pt.GetHashCode()}" + +let pt2 = Point(8, 5) +printfn $"{pt2.GetHashCode()}" +// The example displays output similar to the following. +// Note: HashCode.Combine results are not stable across .NET versions. +// 185727722 +// -363254492 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/ToString/array1.fs b/snippets/fsharp/System/Object/ToString/array1.fs new file mode 100644 index 00000000000..c9ab8a253ba --- /dev/null +++ b/snippets/fsharp/System/Object/ToString/array1.fs @@ -0,0 +1,13 @@ +module array1 + +// +let values = [| 1; 2; 4; 8; 16; 32; 64; 128 |] +printfn $"{values}" + +let list = ResizeArray values +printfn $"{list}" + +// The example displays the following output: +// System.Int32[] +// System.Collections.Generic.List`1[System.Int32] +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/ToString/customize1.fs b/snippets/fsharp/System/Object/ToString/customize1.fs new file mode 100644 index 00000000000..24e73763274 --- /dev/null +++ b/snippets/fsharp/System/Object/ToString/customize1.fs @@ -0,0 +1,25 @@ +module customize1 + +// +open System +open System.Collections.Generic + +type CList<'T>() = + inherit ResizeArray<'T>() + + override this.ToString() = + let mutable retVal = String.Empty + for item in this do + if String.IsNullOrEmpty retVal then + retVal <- retVal + string item + else + retVal <- retVal + $", {item}" + retVal + +let list2 = CList() +list2.Add 1000 +list2.Add 2000 +printfn $"{list2}" +// The example displays the following output: +// 1000, 2000 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/ToString/customize2.fs b/snippets/fsharp/System/Object/ToString/customize2.fs new file mode 100644 index 00000000000..b84893fde8c --- /dev/null +++ b/snippets/fsharp/System/Object/ToString/customize2.fs @@ -0,0 +1,32 @@ +module customize2 + +// +open System +open System.Collections.Generic + +type List<'T> with + member this.ToString2<'T>() = + let mutable retVal = String.Empty + for item in this do + retVal <- retVal + $"""{if String.IsNullOrEmpty retVal then "" else ", "}{item}""" + if String.IsNullOrEmpty retVal then "{}" else "{ " + retVal + " }" + + member this.ToString<'T>(fmt: string) = + let mutable retVal = String.Empty + for item in this do + match box item with + | :? IFormattable as ifmt -> + retVal <- retVal + $"""{if String.IsNullOrEmpty retVal then "" else ", "}{ifmt.ToString(fmt, null)}""" + | _ -> + retVal <- retVal + this.ToString2() + if String.IsNullOrEmpty retVal then "{}" else "{ " + retVal + " }" + +let list = ResizeArray() +list.Add 1000 +list.Add 2000 +printfn $"{list.ToString2()}" +printfn $"""{list.ToString "N0"}""" +// The example displays the following output: +// { 1000, 2000 } +// { 1,000, 2,000 } +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/ToString/tostring1.fs b/snippets/fsharp/System/Object/ToString/tostring1.fs new file mode 100644 index 00000000000..85ffddd04a5 --- /dev/null +++ b/snippets/fsharp/System/Object/ToString/tostring1.fs @@ -0,0 +1,10 @@ +module tostring1 + +// +let obj = obj () +printfn $"{obj.ToString()}" +// printfn $"{obj}" // Equivalent + +// The example displays the following output: +// System.Object +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/ToString/tostring2.fs b/snippets/fsharp/System/Object/ToString/tostring2.fs new file mode 100644 index 00000000000..87dba31ebcf --- /dev/null +++ b/snippets/fsharp/System/Object/ToString/tostring2.fs @@ -0,0 +1,10 @@ +module tostring2 + +// +type Object1() = class end + +let obj1 = Object1() +printfn $"{obj1.ToString()}" +// The example displays the following output: +// Examples.Object1 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/ToString/tostring3.fs b/snippets/fsharp/System/Object/ToString/tostring3.fs new file mode 100644 index 00000000000..28db439aa30 --- /dev/null +++ b/snippets/fsharp/System/Object/ToString/tostring3.fs @@ -0,0 +1,13 @@ +module tostring3 + +// +type Object2(value: obj) = + inherit obj () + override _.ToString() = + base.ToString() + ": " + value.ToString() + +let obj2 = Object2 'a' +printfn $"{obj2.ToString()}" +// The example displays the following output: +// Object2: a +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/ToString/tostringoverload1.fs b/snippets/fsharp/System/Object/ToString/tostringoverload1.fs new file mode 100644 index 00000000000..2c0cc99c7da --- /dev/null +++ b/snippets/fsharp/System/Object/ToString/tostringoverload1.fs @@ -0,0 +1,38 @@ +module tostringoverload1 + +// +open System + +type Automobile(model: string, year: int, doors: int, cylinders: string) = + member _.Doors = doors + member _.Model = model + member _.Year = year + member _.Cylinders = cylinders + + override this.ToString() = + this.ToString "G" + + member _.ToString(fmt) = + let fmt = + if String.IsNullOrEmpty fmt then "G" + else fmt.ToUpperInvariant() + + match fmt with + | "G" -> + $"{year} {model}" + | "D" -> + $"{year} {model}, {doors} dr." + | "C" -> + $"{year} {model}, {cylinders}" + | "A" -> + $"{year} {model}, {doors} dr. {cylinders}" + | _ -> + raise (ArgumentException $"'{fmt}' is an invalid format string") + +let auto = Automobile("Lynx", 2016, 4, "V8") +printfn $"{auto}" +printfn $"""{auto.ToString "A"}""" +// The example displays the following output: +// 2016 Lynx +// 2016 Lynx, 4 dr. V8 +// \ No newline at end of file diff --git a/snippets/fsharp/System/Object/ToString/tostringoverload2.fs b/snippets/fsharp/System/Object/ToString/tostringoverload2.fs new file mode 100644 index 00000000000..c6e7e3e993a --- /dev/null +++ b/snippets/fsharp/System/Object/ToString/tostringoverload2.fs @@ -0,0 +1,18 @@ +module tostringoverload2 + +// +open System.Globalization + +let cultureNames = + [| "en-US"; "en-GB"; "fr-FR"; "hr-HR"; "ja-JP" |] +let value = 1603.49m +for cultureName in cultureNames do + let culture = CultureInfo cultureName + printfn $"""{culture.Name}: {value.ToString("C2", culture)}""" +// The example displays the following output: +// en-US: $1,603.49 +// en-GB: £1,603.49 +// fr-FR: 1 603,49 € +// hr-HR: 1.603,49 kn +// ja-JP: ¥1,603.49 +// \ No newline at end of file diff --git a/snippets/visualbasic/System/IDisposable/Overview/Project.vbproj b/snippets/visualbasic/System/IDisposable/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/IDisposable/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/IDisposable/Overview/base1.vb b/snippets/visualbasic/System/IDisposable/Overview/base1.vb new file mode 100644 index 00000000000..f0e4b14ce75 --- /dev/null +++ b/snippets/visualbasic/System/IDisposable/Overview/base1.vb @@ -0,0 +1,34 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO +Imports System.Runtime.InteropServices + +Class BaseClass1 : Implements IDisposable + ' Flag: Has Dispose already been called? + Dim disposed As Boolean = False + ' Instantiate a FileStream instance. + Dim fs As FileStream = New FileStream("test.txt", FileMode.OpenOrCreate) + + ' Public implementation of Dispose pattern callable by consumers. + Public Sub Dispose() _ + Implements IDisposable.Dispose + Dispose(disposing:=True) + GC.SuppressFinalize(Me) + End Sub + + ' Protected implementation of Dispose pattern. + Protected Overridable Sub Dispose(disposing As Boolean) + If disposed Then Return + + If disposing Then + fs.Dispose() + ' Free any other managed objects here. + ' + End If + + disposed = True + End Sub +End Class +' diff --git a/snippets/visualbasic/System/IDisposable/Overview/base2.vb b/snippets/visualbasic/System/IDisposable/Overview/base2.vb new file mode 100644 index 00000000000..554a3d710c3 --- /dev/null +++ b/snippets/visualbasic/System/IDisposable/Overview/base2.vb @@ -0,0 +1,34 @@ +' Visual Basic .NET Document +Option Strict On + +' +Class BaseClass : Implements IDisposable + ' Flag: Has Dispose already been called? + Dim disposed As Boolean = False + + ' Public implementation of Dispose pattern callable by consumers. + Public Sub Dispose() _ + Implements IDisposable.Dispose + Dispose(disposing:=True) + GC.SuppressFinalize(Me) + End Sub + + ' Protected implementation of Dispose pattern. + Protected Overridable Sub Dispose(disposing As Boolean) + If disposed Then Return + + If disposing Then + ' Free any other managed objects here. + ' + End If + + ' Free any unmanaged objects here. + ' + disposed = True + End Sub + + Protected Overrides Sub Finalize() + Dispose(disposing:=False) + End Sub +End Class +' diff --git a/snippets/visualbasic/System/IDisposable/Overview/calling1.vb b/snippets/visualbasic/System/IDisposable/Overview/calling1.vb new file mode 100644 index 00000000000..1ebfac83b9e --- /dev/null +++ b/snippets/visualbasic/System/IDisposable/Overview/calling1.vb @@ -0,0 +1,52 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO +Imports System.Text.RegularExpressions + +Public Class WordCount + Private filename As String + Private nWords As Integer + Private pattern As String = "\b\w+\b" + + Public Sub New(filename As String) + If Not File.Exists(filename) Then + Throw New FileNotFoundException("The file does not exist.") + End If + + Me.filename = filename + Dim txt As String = String.Empty + Using sr As New StreamReader(filename) + txt = sr.ReadToEnd() + End Using + nWords = Regex.Matches(txt, pattern).Count + End Sub + + Public ReadOnly Property FullName As String + Get + Return filename + End Get + End Property + + Public ReadOnly Property Name As String + Get + Return Path.GetFileName(filename) + End Get + End Property + + Public ReadOnly Property Count As Integer + Get + Return nWords + End Get + End Property +End Class +' + +Public Module Example + Public Sub Main() + Dim wc As New WordCount("C:\users\ronpet\documents\Fr_Mike_Mass.txt") + Console.WriteLine("File {0} ({1}) has {2} words", + wc.Name, wc.FullName, wc.Count) + End Sub +End Module diff --git a/snippets/visualbasic/System/IDisposable/Overview/calling2.vb b/snippets/visualbasic/System/IDisposable/Overview/calling2.vb new file mode 100644 index 00000000000..75957b80d32 --- /dev/null +++ b/snippets/visualbasic/System/IDisposable/Overview/calling2.vb @@ -0,0 +1,56 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO +Imports System.Text.RegularExpressions + +Public Class WordCount2 + Private filename As String + Private nWords As Integer + Private pattern As String = "\b\w+\b" + + Public Sub New(filename As String) + If Not File.Exists(filename) Then + Throw New FileNotFoundException("The file does not exist.") + End If + + Me.filename = filename + Dim txt As String = String.Empty + Dim sr As StreamReader = Nothing + Try + sr = New StreamReader(filename) + txt = sr.ReadToEnd() + Finally + If sr IsNot Nothing Then sr.Dispose() + End Try + nWords = Regex.Matches(txt, pattern).Count + End Sub + + Public ReadOnly Property FullName As String + Get + Return filename + End Get + End Property + + Public ReadOnly Property Name As String + Get + Return Path.GetFileName(filename) + End Get + End Property + + Public ReadOnly Property Count As Integer + Get + Return nWords + End Get + End Property +End Class +' + +Public Module Example2 + Public Sub Main() + Dim wc As New WordCount2("C:\users\ronpet\documents\Fr_Mike_Mass.txt") + Console.WriteLine("File {0} ({1}) has {2} words", + wc.Name, wc.FullName, wc.Count) + End Sub +End Module diff --git a/snippets/visualbasic/System/IDisposable/Overview/derived1.vb b/snippets/visualbasic/System/IDisposable/Overview/derived1.vb new file mode 100644 index 00000000000..1bf423286cd --- /dev/null +++ b/snippets/visualbasic/System/IDisposable/Overview/derived1.vb @@ -0,0 +1,59 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO +Imports System.Runtime.InteropServices + +Class DerivedClass2 : Inherits BaseClass2 + ' Flag: Has Dispose already been called? + Dim disposed As Boolean = False + ' Instantiate a FileStream instance. + Dim fs As FileStream = New FileStream("test.txt", FileMode.OpenOrCreate) + + ' Protected implementation of Dispose pattern. + Protected Overrides Sub Dispose(disposing As Boolean) + If disposed Then Return + + If disposing Then + fs.Dispose() + ' Free any other managed objects here. + ' + End If + + ' Free any unmanaged objects here. + ' + disposed = True + + ' Call base class implementation. + MyBase.Dispose(disposing) + End Sub +End Class +' + +Class BaseClass2 : Implements IDisposable + ' Flag: Has Dispose already been called? + Dim disposed As Boolean = False + + ' Public implementation of Dispose pattern callable by consumers. + Public Sub Dispose() _ + Implements IDisposable.Dispose + Dispose(disposing:=True) + GC.SuppressFinalize(Me) + End Sub + + ' Protected implementation of Dispose pattern. + Protected Overridable Sub Dispose(disposing As Boolean) + If disposed Then Return + + If disposing Then + ' Free any other managed objects here. + ' + End If + + ' Free any unmanaged objects here. + ' + disposed = True + End Sub +End Class + diff --git a/snippets/visualbasic/System/Int32/Overview/Formatting1.vb b/snippets/visualbasic/System/Int32/Overview/Formatting1.vb new file mode 100644 index 00000000000..54fdbc6fed1 --- /dev/null +++ b/snippets/visualbasic/System/Int32/Overview/Formatting1.vb @@ -0,0 +1,53 @@ +' Visual Basic .NET Document +Option Strict On + +Module Example + Public Sub Main() + CallToString() + Console.WriteLine("-----") + CallConvert() + End Sub + + Private Sub CallToString() + ' + Dim numbers() As Integer = { -1403, 0, 169, 1483104 } + For Each number As Integer In numbers + ' Display value using default formatting. + Console.Write("{0,-8} --> ", number.ToString()) + ' Display value with 3 digits and leading zeros. + Console.Write("{0,11:D3}", number) + ' Display value with 1 decimal digit. + Console.Write("{0,13:N1}", number) + ' Display value as hexadecimal. + Console.Write("{0,12:X2}", number) + ' Display value with eight hexadecimal digits. + Console.WriteLine("{0,14:X8}", number) + Next + ' The example displays the following output: + ' -1403 --> -1403 -1,403.0 FFFFFA85 FFFFFA85 + ' 0 --> 000 0.0 00 00000000 + ' 169 --> 169 169.0 A9 000000A9 + ' 1483104 --> 1483104 1,483,104.0 16A160 0016A160 + ' + End Sub + + Private Sub CallConvert() + ' + Dim numbers() As Integer = { -146, 11043, 2781913 } + Console.WriteLine("{0,8} {1,32} {2,11} {3,10}", _ + "Value", "Binary", "Octal", "Hex") + For Each number As Integer In numbers + Console.WriteLine("{0,8} {1,32} {2,11} {3,10}", _ + number, Convert.ToString(number, 2), _ + Convert.ToString(number, 8), _ + Convert.ToString(number, 16)) + Next + ' The example displays the following output: + ' Value Binary Octal Hex + ' -146 11111111111111111111111101101110 37777777556 ffffff6e + ' 11043 10101100100011 25443 2b23 + ' 2781913 1010100111001011011001 12471331 2a72d9 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Int32/Overview/Instantiate1.vb b/snippets/visualbasic/System/Int32/Overview/Instantiate1.vb new file mode 100644 index 00000000000..5dd634995d7 --- /dev/null +++ b/snippets/visualbasic/System/Int32/Overview/Instantiate1.vb @@ -0,0 +1,94 @@ +' Visual Basic .NET Document +Option Strict On + +Imports System.Numerics + +Module Example1 + Public Sub Main() + InstantiateByAssignment() + Console.WriteLine("----") + InstantiateByNarrowingConversion() + Console.WriteLine("----") + Parse() + Console.WriteLine("----") + InstantiateByWideningConversion() + End Sub + + Private Sub InstantiateByAssignment() + ' + Dim number1 As Integer = 64301 + Dim number2 As Integer = 25548612 + ' + End Sub + + Private Sub InstantiateByNarrowingConversion() + ' + Dim lNumber As Long = 163245617 + Try + Dim number1 As Integer = CInt(lNumber) + Console.WriteLine(number1) + Catch e As OverflowException + Console.WriteLine("{0} is out of range of an Int32.", lNumber) + End Try + + Dim dbl2 As Double = 35901.997 + Try + Dim number2 As Integer = CInt(dbl2) + Console.WriteLine(number2) + Catch e As OverflowException + Console.WriteLine("{0} is out of range of an Int32.", dbl2) + End Try + + Dim bigNumber As BigInteger = 132451 + Try + Dim number3 As Integer = CInt(bigNumber) + Console.WriteLine(number3) + Catch e As OverflowException + Console.WriteLine("{0} is out of range of an Int32.", bigNumber) + End Try + ' The example displays the following output: + ' 163245617 + ' 35902 + ' 132451 + ' + End Sub + + Private Sub Parse() + ' + Dim string1 As String = "244681" + Try + Dim number1 As Integer = Int32.Parse(string1) + Console.WriteLine(number1) + Catch e As OverflowException + Console.WriteLine("'{0}' is out of range of a 32-bit integer.", string1) + Catch e As FormatException + Console.WriteLine("The format of '{0}' is invalid.", string1) + End Try + + Dim string2 As String = "F9A3C" + Try + Dim number2 As Integer = Int32.Parse(string2, + System.Globalization.NumberStyles.HexNumber) + Console.WriteLine(number2) + Catch e As OverflowException + Console.WriteLine("'{0}' is out of range of a 32-bit integer.", string2) + Catch e As FormatException + Console.WriteLine("The format of '{0}' is invalid.", string2) + End Try + ' The example displays the following output: + ' 244681 + ' 1022524 + ' + End Sub + + Private Sub InstantiateByWideningConversion() + ' + Dim value1 As SByte = 124 + Dim value2 As Int16 = 1618 + + Dim number1 As Integer = value1 + Dim number2 As Integer = value2 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Int32/Overview/Project.vbproj b/snippets/visualbasic/System/Int32/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Int32/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Int64/Overview/Project.vbproj b/snippets/visualbasic/System/Int64/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Int64/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Int64/Overview/formatting1.vb b/snippets/visualbasic/System/Int64/Overview/formatting1.vb new file mode 100644 index 00000000000..c61d2ae9723 --- /dev/null +++ b/snippets/visualbasic/System/Int64/Overview/formatting1.vb @@ -0,0 +1,62 @@ +' Visual Basic .NET Document +Option Strict On + +Module Example + Public Sub Main() + CallToString() + Console.WriteLine("-----") + CallConvert() + End Sub + + Private Sub CallToString() + ' + Dim numbers() As Long = { -1403, 0, 169, 1483104 } + For Each number In numbers + ' Display value using default formatting. + Console.Write("{0,-8} --> ", number.ToString()) + ' Display value with 3 digits and leading zeros. + Console.Write("{0,8:D3}", number) + ' Display value with 1 decimal digit. + Console.Write("{0,13:N1}", number) + ' Display value as hexadecimal. + Console.Write("{0,18:X2}", number) + ' Display value with eight hexadecimal digits. + Console.WriteLine("{0,18:X8}", number) + Next + ' The example displays the following output: + ' -1403 --> -1403 -1,403.0 FFFFFFFFFFFFFA85 FFFFFFFFFFFFFA85 + ' 0 --> 000 0.0 00 00000000 + ' 169 --> 169 169.0 A9 000000A9 + ' 1483104 --> 1483104 1,483,104.0 16A160 0016A160 + ' + End Sub + + Private Sub CallConvert() + ' + Dim numbers() As Long = { -146, 11043, 2781913 } + For Each number In numbers + Console.WriteLine("{0} (Base 10):", number) + Console.WriteLine(" Binary: {0}", Convert.ToString(number, 2)) + Console.WriteLine(" Octal: {0}", Convert.ToString(number, 8)) + Console.WriteLine(" Hex: {0}", Convert.ToString(number, 16)) + Console.WriteLine() + Next + ' The example displays the following output: + ' -146 (Base 10): + ' Binary: 1111111111111111111111111111111111111111111111111111111101101110 + ' Octal: 1777777777777777777556 + ' Hex: ffffffffffffff6e + ' + ' 11043 (Base 10): + ' Binary: 10101100100011 + ' Octal: 25443 + ' Hex: 2b23 + ' + ' 2781913 (Base 10): + ' Binary: 1010100111001011011001 + ' Octal: 12471331 + ' Hex: 2a72d9 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/Int64/Overview/instantiate1.vb b/snippets/visualbasic/System/Int64/Overview/instantiate1.vb new file mode 100644 index 00000000000..a4df61dcfb0 --- /dev/null +++ b/snippets/visualbasic/System/Int64/Overview/instantiate1.vb @@ -0,0 +1,96 @@ +' Visual Basic .NET Document +Option Strict Off + +Imports System.Numerics + +Module Example1 + Public Sub Main() + InstantiateByAssignment() + Console.WriteLine("----") + InstantiateByNarrowingConversion() + Console.WriteLine("----") + Parse() + Console.WriteLine("----") + InstantiateByWideningConversion() + End Sub + + Private Sub InstantiateByAssignment() + ' + Dim number1 As Long = -64301728 + Dim number2 As Long = 255486129307 + ' + End Sub + + Private Sub InstantiateByNarrowingConversion() + ' + Dim ulNumber As ULong = 163245617943825 + Try + Dim number1 As Long = CLng(ulNumber) + Console.WriteLine(number1) + Catch e As OverflowException + Console.WriteLine("{0} is out of range of an Int64.", ulNumber) + End Try + + Dim dbl2 As Double = 35901.997 + Try + Dim number2 As Long = CLng(dbl2) + Console.WriteLine(number2) + Catch e As OverflowException + Console.WriteLine("{0} is out of range of an Int64.", dbl2) + End Try + + Dim bigNumber As BigInteger = 1.63201978555e30 + Try + Dim number3 As Long = CLng(bigNumber) + Console.WriteLine(number3) + Catch e As OverflowException + Console.WriteLine("{0:N0} is out of range of an Int64.", bigNumber) + End Try + ' The example displays the following output: + ' 163245617943825 + ' 35902 + ' 1,632,019,785,549,999,969,612,091,883,520 is out of range of an Int64. + ' + End Sub + + Private Sub Parse() + ' + Dim string1 As String = "244681903147" + Try + Dim number1 As Long = Int64.Parse(string1) + Console.WriteLine(number1) + Catch e As OverflowException + Console.WriteLine("'{0}' is out of range of a 64-bit integer.", string1) + Catch e As FormatException + Console.WriteLine("The format of '{0}' is invalid.", string1) + End Try + + Dim string2 As String = "F9A3CFF0A" + Try + Dim number2 As Long = Int64.Parse(string2, + System.Globalization.NumberStyles.HexNumber) + Console.WriteLine(number2) + Catch e As OverflowException + Console.WriteLine("'{0}' is out of range of a 64-bit integer.", string2) + Catch e As FormatException + Console.WriteLine("The format of '{0}' is invalid.", string2) + End Try + ' The example displays the following output: + ' 244681903147 + ' 67012198154 + ' + End Sub + + Private Sub InstantiateByWideningConversion() + ' + Dim value1 As SByte = 124 + Dim value2 As Int16 = 1618 + Dim value3 As Int32 = Int32.MaxValue + + Dim number1 As Long = value1 + Dim number2 As Long = value2 + Dim number3 As Long = value3 + ' + End Sub +End Module + diff --git a/snippets/visualbasic/System/InvalidCastException/Overview/Interface1.vb b/snippets/visualbasic/System/InvalidCastException/Overview/Interface1.vb new file mode 100644 index 00000000000..9632e6357da --- /dev/null +++ b/snippets/visualbasic/System/InvalidCastException/Overview/Interface1.vb @@ -0,0 +1,20 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Globalization + +Module Example3 + Public Sub Main() + Dim culture As CultureInfo = CultureInfo.InvariantCulture + Dim provider As IFormatProvider = culture + + Dim dt As DateTimeFormatInfo = CType(provider, DateTimeFormatInfo) + End Sub +End Module +' The example displays the following output: +' Unhandled Exception: System.InvalidCastException: +' Unable to cast object of type 'System.Globalization.CultureInfo' to +' type 'System.Globalization.DateTimeFormatInfo'. +' at Example.Main() +' diff --git a/snippets/visualbasic/System/InvalidCastException/Overview/Project.vbproj b/snippets/visualbasic/System/InvalidCastException/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/InvalidCastException/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/InvalidCastException/Overview/basetoderived1.vb b/snippets/visualbasic/System/InvalidCastException/Overview/basetoderived1.vb new file mode 100644 index 00000000000..06596be0ffc --- /dev/null +++ b/snippets/visualbasic/System/InvalidCastException/Overview/basetoderived1.vb @@ -0,0 +1,67 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Class Person + Dim _name As String + + Public Property Name As String + Get + Return _name + End Get + Set + _name = value + End Set + End Property +End Class + +Public Class PersonWithID : Inherits Person + Dim _id As String + + Public Property Id As String + Get + Return _id + End Get + Set + _id = value + End Set + End Property +End Class + +Module Example1 + Public Sub Main() + Dim p As New Person() + p.Name = "John" + Try + Dim pid As PersonWithID = CType(p, PersonWithID) + Console.WriteLine("Conversion succeeded.") + Catch e As InvalidCastException + Console.WriteLine("Conversion failed.") + End Try + + Dim pid1 As New PersonWithID() + pid1.Name = "John" + pid1.Id = "246" + Dim p1 As Person = pid1 + + Try + Dim pid1a As PersonWithID = CType(p1, PersonWithID) + Console.WriteLine("Conversion succeeded.") + Catch e As InvalidCastException + Console.WriteLine("Conversion failed.") + End Try + + Dim p2 As Person = Nothing + Try + Dim pid2 As PersonWithID = CType(p2, PersonWithID) + Console.WriteLine("Conversion succeeded.") + Catch e As InvalidCastException + Console.WriteLine("Conversion failed.") + End Try + End Sub +End Module +' The example displays the following output: +' Conversion failed. +' Conversion succeeded. +' Conversion succeeded. +' diff --git a/snippets/visualbasic/System/InvalidCastException/Overview/iconvertible1.vb b/snippets/visualbasic/System/InvalidCastException/Overview/iconvertible1.vb new file mode 100644 index 00000000000..692bc73fa4f --- /dev/null +++ b/snippets/visualbasic/System/InvalidCastException/Overview/iconvertible1.vb @@ -0,0 +1,27 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example2 + Public Sub Main() + Dim flag As Boolean = True + Try + Dim conv As IConvertible = flag + Dim ch As Char = conv.ToChar(Nothing) + Console.WriteLine("Conversion succeeded.") + Catch e As InvalidCastException + Console.WriteLine("Cannot convert a Boolean to a Char.") + End Try + + Try + Dim ch As Char = Convert.ToChar(flag) + Console.WriteLine("Conversion succeeded.") + Catch e As InvalidCastException + Console.WriteLine("Cannot convert a Boolean to a Char.") + End Try + End Sub +End Module +' The example displays the following output: +' Cannot convert a Boolean to a Char. +' Cannot convert a Boolean to a Char. +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable1.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable1.vb new file mode 100644 index 00000000000..0a2e83e32ff --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable1.vb @@ -0,0 +1,19 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Linq + +Module Example + Public Sub Main() + Dim data() As Integer = { 1, 2, 3, 4 } + Dim average = data.Where(Function(num) num > 4).Average() + Console.Write("The average of numbers greater than 4 is {0}", + average) + End Sub +End Module +' The example displays the following output: +' Unhandled Exception: System.InvalidOperationException: Sequence contains no elements +' at System.Linq.Enumerable.Average(IEnumerable`1 source) +' at Example.Main() +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable2.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable2.vb new file mode 100644 index 00000000000..a7321693d72 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable2.vb @@ -0,0 +1,23 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Linq + +Module Example1 + Public Sub Main() + Dim dbQueryResults() As Integer = {1, 2, 3, 4} + Dim moreThan4 = dbQueryResults.Where(Function(num) num > 4) + + If moreThan4.Any() Then + Console.WriteLine("Average value of numbers greater than 4: {0}:", + moreThan4.Average()) + Else + ' Handle empty collection. + Console.WriteLine("The dataset has no values greater than 4.") + End If + End Sub +End Module +' The example displays the following output: +' The dataset has no values greater than 4. +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable3.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable3.vb new file mode 100644 index 00000000000..56ce9767fb6 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable3.vb @@ -0,0 +1,22 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Linq + +Module Example2 + Public Sub Main() + Dim dbQueryResults() As Integer = {1, 2, 3, 4} + + Dim firstNum = dbQueryResults.First(Function(n) n > 4) + + Console.WriteLine("The first value greater than 4 is {0}", + firstNum) + End Sub +End Module +' The example displays the following output: +' Unhandled Exception: System.InvalidOperationException: +' Sequence contains no matching element +' at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate) +' at Example.Main() +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable4.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable4.vb new file mode 100644 index 00000000000..4210a9f94b3 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable4.vb @@ -0,0 +1,23 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Linq + +Module Example3 + Public Sub Main() + Dim dbQueryResults() As Integer = {1, 2, 3, 4} + + Dim firstNum = dbQueryResults.FirstOrDefault(Function(n) n > 4) + + If firstNum = 0 Then + Console.WriteLine("No value is greater than 4.") + Else + Console.WriteLine("The first value greater than 4 is {0}", + firstNum) + End If + End Sub +End Module +' The example displays the following output: +' No value is greater than 4. +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable5.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable5.vb new file mode 100644 index 00000000000..95dd8c92560 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable5.vb @@ -0,0 +1,23 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Linq + +Module Example4 + Public Sub Main() + Dim dbQueryResults() As Integer = {1, 2, 3, 4} + + Dim singleObject = dbQueryResults.Single(Function(value) value > 4) + + ' Display results. + Console.WriteLine("{0} is the only value greater than 4", + singleObject) + End Sub +End Module +' The example displays the following output: +' Unhandled Exception: System.InvalidOperationException: +' Sequence contains no matching element +' at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate) +' at Example.Main() +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable6.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable6.vb new file mode 100644 index 00000000000..ec5792b06db --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable6.vb @@ -0,0 +1,27 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Linq + +Module Example5 + Public Sub Main() + Dim dbQueryResults() As Integer = {1, 2, 3, 4} + + Dim singleObject = dbQueryResults.SingleOrDefault(Function(value) value > 2) + + If singleObject <> 0 Then + Console.WriteLine("{0} is the only value greater than 2", + singleObject) + Else + ' Handle an empty collection. + Console.WriteLine("No value is greater than 2") + End If + End Sub +End Module +' The example displays the following output: +' Unhandled Exception: System.InvalidOperationException: +' Sequence contains more than one matching element +' at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) +' at Example.Main() +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating1.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating1.vb new file mode 100644 index 00000000000..7011d5a65ae --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating1.vb @@ -0,0 +1,30 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Module Example6 + Public Sub Main() + Dim numbers As New List(Of Integer)({1, 2, 3, 4, 5}) + For Each number In numbers + Dim square As Integer = CInt(Math.Pow(number, 2)) + Console.WriteLine("{0}^{1}", number, square) + Console.WriteLine("Adding {0} to the collection..." + vbCrLf, + square) + numbers.Add(square) + Next + End Sub +End Module +' The example displays the following output: +' 1^1 +' Adding 1 to the collection... +' +' +' Unhandled Exception: System.InvalidOperationException: Collection was modified; +' enumeration operation may not execute. +' at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +' at System.Collections.Generic.List`1.Enumerator.MoveNextRare() +' at Example.Main() +' + diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating2.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating2.vb new file mode 100644 index 00000000000..e57b706ce55 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating2.vb @@ -0,0 +1,44 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Module Example7 + Public Sub Main() + Dim numbers As New List(Of Integer)({1, 2, 3, 4, 5}) + Dim upperBound = numbers.Count - 1 + + For ctr As Integer = 0 To upperBound + Dim square As Integer = CInt(Math.Pow(numbers(ctr), 2)) + Console.WriteLine("{0}^{1}", numbers(ctr), square) + Console.WriteLine("Adding {0} to the collection..." + vbCrLf, + square) + numbers.Add(square) + Next + + Console.WriteLine("Elements now in the collection: ") + For Each number In numbers + Console.Write("{0} ", number) + Next + End Sub +End Module +' The example displays the following output: +' 1^1 +' Adding 1 to the collection... +' +' 2^4 +' Adding 4 to the collection... +' +' 3^9 +' Adding 9 to the collection... +' +' 4^16 +' Adding 16 to the collection... +' +' 5^25 +' Adding 25 to the collection... +' +' Elements now in the collection: +' 1 2 3 4 5 1 4 9 16 25 +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating3.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating3.vb new file mode 100644 index 00000000000..74736665135 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating3.vb @@ -0,0 +1,31 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Module Example8 + Public Sub Main() + Dim numbers As New List(Of Integer)({1, 2, 3, 4, 5}) + Dim temp As New List(Of Integer)() + + ' Square each number and store it in a temporary collection. + For Each number In numbers + Dim square As Integer = CInt(Math.Pow(number, 2)) + temp.Add(square) + Next + + ' Combine the numbers into a single array. + Dim combined(numbers.Count + temp.Count - 1) As Integer + Array.Copy(numbers.ToArray(), 0, combined, 0, numbers.Count) + Array.Copy(temp.ToArray(), 0, combined, numbers.Count, temp.Count) + + ' Iterate the array. + For Each value In combined + Console.Write("{0} ", value) + Next + End Sub +End Module +' The example displays the following output: +' 1 2 3 4 5 1 4 9 16 25 +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort1.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort1.vb new file mode 100644 index 00000000000..dbb0df27791 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort1.vb @@ -0,0 +1,43 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Public Class Person9 + Public Sub New(fName As String, lName As String) + FirstName = fName + LastName = lName + End Sub + + Public Property FirstName As String + Public Property LastName As String +End Class + +Module Example9 + Public Sub Main() + Dim people As New List(Of Person9)() + + people.Add(New Person9("John", "Doe")) + people.Add(New Person9("Jane", "Doe")) + people.Sort() + For Each person In people + Console.WriteLine("{0} {1}", person.FirstName, person.LastName) + Next + End Sub +End Module +' The example displays the following output: +' Unhandled Exception: System.InvalidOperationException: Failed to compare two elements in the array. ---> +' System.ArgumentException: At least one object must implement IComparable. +' at System.Collections.Comparer.Compare(Object a, Object b) +' at System.Collections.Generic.ArraySortHelper`1.SwapIfGreater(T[] keys, IComparer`1 comparer, Int32 a, Int32 b) +' at System.Collections.Generic.ArraySortHelper`1.DepthLimitedQuickSort(T[] keys, Int32 left, Int32 right, IComparer`1 comparer, Int32 depthLimit) +' at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer) +' --- End of inner exception stack trace --- +' at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer) +' at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer) +' at System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer) +' at Example.Main() +' + + diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort2.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort2.vb new file mode 100644 index 00000000000..a5f67a5ee67 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort2.vb @@ -0,0 +1,38 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Public Class Person : Implements IComparable(Of Person) + Public Sub New(fName As String, lName As String) + FirstName = fName + LastName = lName + End Sub + + Public Property FirstName As String + Public Property LastName As String + + Public Function CompareTo(other As Person) As Integer _ + Implements IComparable(Of Person).CompareTo + Return String.Format("{0} {1}", LastName, FirstName). + CompareTo(String.Format("{0} {1}", other.LastName, other.FirstName)) + End Function +End Class + +Module Example10 + Public Sub Main() + Dim people As New List(Of Person)() + + people.Add(New Person("John", "Doe")) + people.Add(New Person("Jane", "Doe")) + people.Sort() + For Each person In people + Console.WriteLine("{0} {1}", person.FirstName, person.LastName) + Next + End Sub +End Module +' The example displays the following output: +' Jane Doe +' John Doe +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort3.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort3.vb new file mode 100644 index 00000000000..1ea32e88e41 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort3.vb @@ -0,0 +1,41 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Public Class Person11 + Public Sub New(fName As String, lName As String) + FirstName = fName + LastName = lName + End Sub + + Public Property FirstName As String + Public Property LastName As String +End Class + +Public Class PersonComparer : Implements IComparer(Of Person11) + Public Function Compare(x As Person11, y As Person11) As Integer _ + Implements IComparer(Of Person11).Compare + Return String.Format("{0} {1}", x.LastName, x.FirstName). + CompareTo(String.Format("{0} {1}", y.LastName, y.FirstName)) + End Function +End Class + +Module Example11 + Public Sub Main() + Dim people As New List(Of Person11)() + + people.Add(New Person11("John", "Doe")) + people.Add(New Person11("Jane", "Doe")) + people.Sort(New PersonComparer()) + For Each person In people + Console.WriteLine("{0} {1}", person.FirstName, person.LastName) + Next + End Sub +End Module +' The example displays the following output: +' Jane Doe +' John Doe +' + diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort4.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort4.vb new file mode 100644 index 00000000000..8181874eb39 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort4.vb @@ -0,0 +1,37 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Public Class Person12 + Public Sub New(fName As String, lName As String) + FirstName = fName + LastName = lName + End Sub + + Public Property FirstName As String + Public Property LastName As String +End Class + +Module Example12 + Public Sub Main() + Dim people As New List(Of Person12)() + + people.Add(New Person12("John", "Doe")) + people.Add(New Person12("Jane", "Doe")) + people.Sort(AddressOf PersonComparison) + For Each person In people + Console.WriteLine("{0} {1}", person.FirstName, person.LastName) + Next + End Sub + + Public Function PersonComparison(x As Person12, y As Person12) As Integer + Return String.Format("{0} {1}", x.LastName, x.FirstName). + CompareTo(String.Format("{0} {1}", y.LastName, y.FirstName)) + End Function +End Module +' The example displays the following output: +' Jane Doe +' John Doe +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Nullable1.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Nullable1.vb new file mode 100644 index 00000000000..e03d88f73f9 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Nullable1.vb @@ -0,0 +1,27 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Linq + +Module Example13 + Public Sub Main() + Dim queryResult = New Integer?() {1, 2, Nothing, 4} + Dim map = queryResult.Select(Function(nullableInt) CInt(nullableInt)) + + ' Display list. + For Each num In map + Console.Write("{0} ", num) + Next + Console.WriteLine() + End Sub +End Module + +' The example displays the following output: +' 1 2 +' Unhandled Exception: System.InvalidOperationException: Nullable object must have a value. +' at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +' at Example.
b__0(Nullable`1 nullableInt) +' at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() +' at Example.Main() +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Nullable2.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Nullable2.vb new file mode 100644 index 00000000000..8de19feb2eb --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Nullable2.vb @@ -0,0 +1,32 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Linq + +Module Example14 + Public Sub Main() + Dim queryResult = New Integer?() {1, 2, Nothing, 4} + Dim numbers = queryResult.Select(Function(nullableInt) _ + CInt(nullableInt.GetValueOrDefault())) + ' Display list. + For Each number In numbers + Console.Write("{0} ", number) + Next + Console.WriteLine() + + ' Use -1 to indicate a missing values. + numbers = queryResult.Select(Function(nullableInt) _ + CInt(If(nullableInt.HasValue, nullableInt, -1))) + ' Display list. + For Each number In numbers + Console.Write("{0} ", number) + Next + Console.WriteLine() + + End Sub +End Module +' The example displays the following output: +' 1 2 0 4 +' 1 2 -1 4 +' diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Project.vbproj b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form1.Designer.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form1.Designer.vb new file mode 100644 index 00000000000..ae7f77549c5 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form1.Designer.vb @@ -0,0 +1,64 @@ +Imports System.Drawing +Imports System.Windows.Forms + + +Partial Class Form1 + Inherits System.Windows.Forms.Form + + 'Form overrides dispose to clean up the component list. + + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + + Private Sub InitializeComponent() + Button1 = New Button() + TextBox1 = New TextBox() + SuspendLayout() + ' + ' Button1 + ' + Button1.Location = New Point(99, 52) + Button1.Name = "Button1" + Button1.Size = New Size(112, 34) + Button1.TabIndex = 0 + Button1.Text = "Button1" + Button1.UseVisualStyleBackColor = True + ' + ' TextBox1 + ' + TextBox1.Location = New Point(99, 111) + TextBox1.Name = "TextBox1" + TextBox1.Size = New Size(150, 31) + TextBox1.TabIndex = 1 + ' + ' Form1 + ' + AutoScaleDimensions = New SizeF(10F, 25F) + AutoScaleMode = AutoScaleMode.Font + ClientSize = New Size(800, 450) + Controls.Add(TextBox1) + Controls.Add(Button1) + Name = "Form1" + Text = "Form1" + ResumeLayout(False) + PerformLayout() + End Sub + + Friend WithEvents Button1 As Button + Friend WithEvents TextBox1 As TextBox + +End Class diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form1.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form1.vb new file mode 100644 index 00000000000..417796c24c9 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form1.vb @@ -0,0 +1,29 @@ +Public Class Form1 + ' + Dim lines As New List(Of String)() + Private Async Sub threadExampleBtn_Click(sender As Object, e As EventArgs) Handles Button1.Click + TextBox1.Text = String.Empty + lines.Clear() + + lines.Add("Simulating work on UI thread.") + TextBox1.Lines = lines.ToArray() + DoSomeWork(20) + + lines.Add("Simulating work on non-UI thread.") + TextBox1.Lines = lines.ToArray() + Await Task.Run(Sub() DoSomeWork(1000)) + + lines.Add("ThreadsExampleBtn_Click completes. ") + TextBox1.Lines = lines.ToArray() + End Sub + + Private Async Sub DoSomeWork(milliseconds As Integer) + ' Simulate work. + Await Task.Delay(milliseconds) + + ' Report completion. + lines.Add(String.Format("Some work completed in {0} ms on UI thread.", milliseconds)) + TextBox1.Lines = lines.ToArray() + End Sub + ' +End Class diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form11.Designer.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form11.Designer.vb new file mode 100644 index 00000000000..11ee041fc76 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form11.Designer.vb @@ -0,0 +1,63 @@ +Imports System.Drawing +Imports System.Windows.Forms + + +Partial Class Form11 + Inherits System.Windows.Forms.Form + + 'Form overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + Button1 = New Button() + TextBox1 = New TextBox() + SuspendLayout() + ' + ' Button1 + ' + Button1.Location = New Point(58, 44) + Button1.Name = "Button1" + Button1.Size = New Size(112, 34) + Button1.TabIndex = 0 + Button1.Text = "Button1" + Button1.UseVisualStyleBackColor = True + ' + ' TextBox1 + ' + TextBox1.Location = New Point(60, 100) + TextBox1.Name = "TextBox1" + TextBox1.Size = New Size(150, 31) + TextBox1.TabIndex = 1 + ' + ' Form11 + ' + AutoScaleDimensions = New SizeF(10F, 25F) + AutoScaleMode = AutoScaleMode.Font + ClientSize = New Size(800, 450) + Controls.Add(TextBox1) + Controls.Add(Button1) + Name = "Form11" + Text = "Form11" + ResumeLayout(False) + PerformLayout() + End Sub + + Friend WithEvents Button1 As Button + Friend WithEvents TextBox1 As TextBox +End Class diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form11.vb b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form11.vb new file mode 100644 index 00000000000..76551cb4266 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form11.vb @@ -0,0 +1,39 @@ +Public Class Form11 + + Dim lines As New List(Of String)() + + Private Async Sub threadExampleBtn_Click(sender As Object, e As EventArgs) Handles Button1.Click + TextBox1.Text = String.Empty + lines.Clear() + + lines.Add("Simulating work on UI thread.") + TextBox1.Lines = lines.ToArray() + DoSomeWork(20) + + lines.Add("Simulating work on non-UI thread.") + TextBox1.Lines = lines.ToArray() + Await Task.Run(Sub() DoSomeWork(1000)) + + lines.Add("ThreadsExampleBtn_Click completes. ") + TextBox1.Lines = lines.ToArray() + End Sub + + ' + Private Async Sub DoSomeWork(milliseconds As Integer) + ' Simulate work. + Await Task.Delay(milliseconds) + + ' Report completion. + Dim uiMarshal As Boolean = TextBox1.InvokeRequired + Dim msg As String = String.Format("Some work completed in {0} ms. on {1}UI thread" + vbCrLf, + milliseconds, If(uiMarshal, String.Empty, "non-")) + lines.Add(msg) + + If uiMarshal Then + TextBox1.Invoke(New Action(Sub() TextBox1.Lines = lines.ToArray())) + Else + TextBox1.Lines = lines.ToArray() + End If + End Sub + ' +End Class diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/My Project/Application.myapp b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/My Project/Application.myapp new file mode 100644 index 00000000000..131837652e3 --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/My Project/Application.myapp @@ -0,0 +1,10 @@ + + + true + + false + 0 + true + 0 + true + \ No newline at end of file diff --git a/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/project.vbproj b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/project.vbproj new file mode 100644 index 00000000000..64eaf863cbf --- /dev/null +++ b/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/project.vbproj @@ -0,0 +1,11 @@ + + + + WinExe + net10.0-windows + true + WindowsForms + project.My.MyApplication + + + diff --git a/snippets/visualbasic/System/NotSupportedException/Overview/BadState1.vb b/snippets/visualbasic/System/NotSupportedException/Overview/BadState1.vb new file mode 100644 index 00000000000..682e15bf30a --- /dev/null +++ b/snippets/visualbasic/System/NotSupportedException/Overview/BadState1.vb @@ -0,0 +1,37 @@ +' Visual Basic .NET Document +Option Strict On +' +Imports System.IO +Imports System.Text +Imports System.Threading.Tasks + +Module Example + Public Sub Main() + Dim enc As Encoding = Encoding.Unicode + Dim value As String = "This is a string to persist." + Dim bytes() As Byte = enc.GetBytes(value) + + Dim fs As New FileStream(".\TestFile.dat", + FileMode.Open, + FileAccess.Read) + Dim t As Task = fs.WriteAsync(enc.GetPreamble(), 0, enc.GetPreamble().Length) + Dim t2 As Task = t.ContinueWith(Sub(a) fs.WriteAsync(bytes, 0, bytes.Length)) + t2.Wait() + fs.Close() + End Sub +End Module +' The example displays the following output: +' Unhandled Exception: System.NotSupportedException: Stream does not support writing. +' at System.IO.Stream.BeginWriteInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state +' , Boolean serializeAsynchronously) +' at System.IO.FileStream.BeginWrite(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object sta +' teObject) +' at System.IO.Stream.<>c.b__53_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, +' Object state) +' at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMet +' hod, Func`3 endMethod) +' at System.IO.Stream.BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count) +' at System.IO.FileStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) +' at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count) +' at Example.Main() +' diff --git a/snippets/visualbasic/System/NotSupportedException/Overview/Project.vbproj b/snippets/visualbasic/System/NotSupportedException/Overview/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/NotSupportedException/Overview/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/NotSupportedException/Overview/TestProp1.vb b/snippets/visualbasic/System/NotSupportedException/Overview/TestProp1.vb new file mode 100644 index 00000000000..169a96195e8 --- /dev/null +++ b/snippets/visualbasic/System/NotSupportedException/Overview/TestProp1.vb @@ -0,0 +1,70 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.IO +Imports System.Threading.Tasks + +Module Example2 + Public Sub Main() + Dim name As String = ".\TestFile.dat" + Dim fs As New FileStream(name, + FileMode.Create, + FileAccess.Write) + Console.WriteLine("Filename: {0}, Encoding: {1}", + name, FileUtilities2.GetEncodingType(fs)) + End Sub +End Module + +Public Class FileUtilities2 + Public Enum EncodingType As Integer + None = 0 + Unknown = -1 + Utf8 = 1 + Utf16 = 2 + Utf32 = 3 + End Enum + + Public Shared Function GetEncodingType(fs As FileStream) As EncodingType + Dim bytes(3) As Byte + Dim t As Task(Of Integer) = fs.ReadAsync(bytes, 0, 4) + t.Wait() + Dim bytesRead As Integer = t.Result + If bytesRead < 2 Then Return EncodingType.None + + If bytesRead >= 3 And (bytes(0) = &HEF AndAlso bytes(1) = &HBB AndAlso bytes(2) = &HBF) Then + Return EncodingType.Utf8 + End If + + If bytesRead = 4 Then + Dim value As UInteger = BitConverter.ToUInt32(bytes, 0) + If value = &HFEFF Or value = &HFEFF0000 Then + Return EncodingType.Utf32 + End If + End If + + Dim value16 As UInt16 = BitConverter.ToUInt16(bytes, 0) + If value16 = &HFEFF Or value16 = &HFFFE Then + Return EncodingType.Utf16 + End If + + Return EncodingType.Unknown + End Function +End Class +' The example displays the following output: +' Unhandled Exception: System.NotSupportedException: Stream does not support reading. +' at System.IO.Stream.BeginReadInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state, +' Boolean serializeAsynchronously) +' at System.IO.FileStream.BeginRead(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object stat +' eObject) +' at System.IO.Stream.<>c.b__43_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, O +' bject state) +' at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMet +' hod, Func`3 endMethod) +' at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count) +' at System.IO.FileStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) +' at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count) +' at FileUtilities2.GetEncodingType(FileStream fs) +' at Example.Main() +' + diff --git a/snippets/visualbasic/System/NotSupportedException/Overview/TestProp2.vb b/snippets/visualbasic/System/NotSupportedException/Overview/TestProp2.vb new file mode 100644 index 00000000000..137c7393e5e --- /dev/null +++ b/snippets/visualbasic/System/NotSupportedException/Overview/TestProp2.vb @@ -0,0 +1,61 @@ +' Visual Basic .NET Document +Option Strict On + +Imports System.IO +Imports System.Threading.Tasks + +Module Example3 + Public Sub Main() + Dim name As String = ".\TestFile.dat" + Dim fs As New FileStream(name, + FileMode.Create, + FileAccess.Write) + Console.WriteLine("Filename: {0}, Encoding: {1}", + name, FileUtilities3.GetEncodingType(fs)) + End Sub +End Module + +' +Public Class FileUtilities3 + Public Enum EncodingType As Integer + None = 0 + Unknown = -1 + Utf8 = 1 + Utf16 = 2 + Utf32 = 3 + End Enum + + Public Shared Function GetEncodingType(fs As FileStream) As EncodingType + If Not fs.CanRead Then + Return EncodingType.Unknown + End If + + Dim bytes(3) As Byte + Dim t As Task(Of Integer) = fs.ReadAsync(bytes, 0, 4) + t.Wait() + Dim bytesRead As Integer = t.Result + If bytesRead < 2 Then Return EncodingType.None + + If bytesRead >= 3 And (bytes(0) = &HEF AndAlso bytes(1) = &HBB AndAlso bytes(2) = &HBF) Then + Return EncodingType.Utf8 + End If + + If bytesRead = 4 Then + Dim value As UInteger = BitConverter.ToUInt32(bytes, 0) + If value = &HFEFF Or value = &HFEFF0000 Then + Return EncodingType.Utf32 + End If + End If + + Dim value16 As UInt16 = BitConverter.ToUInt16(bytes, 0) + If value16 = &HFEFF Or value16 = &HFFFE Then + Return EncodingType.Utf16 + End If + + Return EncodingType.Unknown + End Function +End Class +' The example displays the following output: +' Filename: .\TestFile.dat, Encoding: Unknown +' + diff --git a/snippets/visualbasic/System/Object/Equals/Project.vbproj b/snippets/visualbasic/System/Object/Equals/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Object/Equals/equals2.vb b/snippets/visualbasic/System/Object/Equals/equals2.vb new file mode 100644 index 00000000000..7c50d1f41df --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/equals2.vb @@ -0,0 +1,82 @@ +' +Class Point1 + Protected x, y As Integer + + Public Sub New() + Me.x = 0 + Me.y = 0 + End Sub + + Public Sub New(x As Integer, y As Integer) + Me.x = x + Me.y = y + End Sub + + Public Overrides Function Equals(obj As Object) As Boolean + ' Check for null and compare run-time types. + If obj Is Nothing OrElse Not Me.GetType().Equals(obj.GetType()) Then + Return False + Else + Dim p As Point1 = DirectCast(obj, Point1) + Return x = p.x AndAlso y = p.y + End If + End Function + + Public Overrides Function GetHashCode() As Integer + Return HashCode.Combine(x, y) + End Function + + Public Overrides Function ToString() As String + Return String.Format("Point1({0}, {1})", x, y) + End Function +End Class + +Class Point3D : Inherits Point1 + Private z As Integer + + Public Sub New(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) + MyBase.New(x, y) + Me.z = z + End Sub + + Public Overrides Function Equals(ByVal obj As Object) As Boolean + Dim pt3 As Point3D = TryCast(obj, Point3D) + If pt3 Is Nothing Then + Return False + Else + Return MyBase.Equals(CType(pt3, Point1)) AndAlso z = pt3.z + End If + End Function + + Public Overrides Function GetHashCode() As Integer + Return HashCode.Combine(MyBase.GetHashCode(), z) + End Function + + Public Overrides Function ToString() As String + Return String.Format("Point1({0}, {1}, {2})", x, y, z) + End Function +End Class + +Module Example2 + Public Sub Main() + Dim point2D As New Point1(5, 5) + Dim point3Da As New Point3D(5, 5, 2) + Dim point3Db As New Point3D(5, 5, 2) + Dim point3Dc As New Point3D(5, 5, -1) + + Console.WriteLine("{0} = {1}: {2}", + point2D, point3Da, point2D.Equals(point3Da)) + Console.WriteLine("{0} = {1}: {2}", + point2D, point3Db, point2D.Equals(point3Db)) + Console.WriteLine("{0} = {1}: {2}", + point3Da, point3Db, point3Da.Equals(point3Db)) + Console.WriteLine("{0} = {1}: {2}", + point3Da, point3Dc, point3Da.Equals(point3Dc)) + End Sub +End Module +' The example displays the following output +' Point1(5, 5) = Point1(5, 5, 2): False +' Point1(5, 5) = Point1(5, 5, 2): False +' Point1(5, 5, 2) = Point1(5, 5, 2): True +' Point1(5, 5, 2) = Point1(5, 5, -1): False +' diff --git a/snippets/visualbasic/System/Object/Equals/equals3.vb b/snippets/visualbasic/System/Object/Equals/equals3.vb new file mode 100644 index 00000000000..6ce5dedf7e1 --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/equals3.vb @@ -0,0 +1,70 @@ +' +Class Rectangle + Private a, b As Point + + Public Sub New(ByVal upLeftX As Integer, ByVal upLeftY As Integer, _ + ByVal downRightX As Integer, ByVal downRightY As Integer) + Me.a = New Point(upLeftX, upLeftY) + Me.b = New Point(downRightX, downRightY) + End Sub + + Public Overrides Function Equals(ByVal obj As [Object]) As Boolean + ' Performs an equality check on two rectangles (Point object pairs). + If obj Is Nothing OrElse Not [GetType]().Equals(obj.GetType()) Then + Return False + End If + Dim r As Rectangle = CType(obj, Rectangle) + Return a.Equals(r.a) AndAlso b.Equals(r.b) + End Function + + Public Overrides Function GetHashCode() As Integer + Return Tuple.Create(a, b).GetHashCode() + End Function + + Public Overrides Function ToString() As String + Return String.Format("Rectangle({0}, {1}, {2}, {3})", + a.x, a.y, b.x, b.y) + End Function +End Class + +Class Point + Friend x As Integer + Friend y As Integer + + Public Sub New(ByVal X As Integer, ByVal Y As Integer) + Me.x = X + Me.y = Y + End Sub + + Public Overrides Function Equals(ByVal obj As [Object]) As Boolean + ' Performs an equality check on two points (integer pairs). + If obj Is Nothing OrElse Not [GetType]().Equals(obj.GetType()) Then + Return False + Else + Dim p As Point = CType(obj, Point) + Return x = p.x AndAlso y = p.y + End If + End Function + + Public Overrides Function GetHashCode() As Integer + Return Tuple.Create(x, y).GetHashCode() + End Function +End Class + +Class Example3 + Public Shared Sub Main() + Dim r1 As New Rectangle(0, 0, 100, 200) + Dim r2 As New Rectangle(0, 0, 100, 200) + Dim r3 As New Rectangle(0, 0, 150, 200) + + Console.WriteLine("{0} = {1}: {2}", r1, r2, r1.Equals(r2)) + Console.WriteLine("{0} = {1}: {2}", r1, r3, r1.Equals(r3)) + Console.WriteLine("{0} = {1}: {2}", r2, r3, r2.Equals(r3)) + End Sub +End Class + +' The example displays the following output: +' Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 100, 200): True +' Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False +' Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False +' diff --git a/snippets/visualbasic/System/Object/Equals/equals4.vb b/snippets/visualbasic/System/Object/Equals/equals4.vb new file mode 100644 index 00000000000..9051d6445b4 --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/equals4.vb @@ -0,0 +1,50 @@ +' +Public Structure Complex + Public re, im As Double + + Public Overrides Function Equals(ByVal obj As [Object]) As Boolean + Return TypeOf obj Is Complex AndAlso Me = CType(obj, Complex) + End Function + + Public Overrides Function GetHashCode() As Integer + Return Tuple.Create(re, im).GetHashCode() + End Function + + Public Shared Operator = (x As Complex, y As Complex) As Boolean + Return x.re = y.re AndAlso x.im = y.im + End Operator + + Public Shared Operator <> (x As Complex, y As Complex) As Boolean + Return Not (x = y) + End Operator + + Public Overrides Function ToString() As String + Return String.Format("({0}, {1})", re, im) + End Function +End Structure + +Class Example8 + Public Shared Sub Main() + Dim cmplx1, cmplx2 As Complex + + cmplx1.re = 4.0 + cmplx1.im = 1.0 + + cmplx2.re = 2.0 + cmplx2.im = 1.0 + + Console.WriteLine("{0} <> {1}: {2}", cmplx1, cmplx2, cmplx1 <> cmplx2) + Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2)) + + cmplx2.re = 4.0 + + Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1 = cmplx2) + Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2)) + End Sub +End Class +' The example displays the following output: +' (4, 1) <> (2, 1): True +' (4, 1) = (2, 1): False +' (4, 1) = (4, 1): True +' (4, 1) = (4, 1): True +' diff --git a/snippets/visualbasic/System/Object/Equals/equals_ref.vb b/snippets/visualbasic/System/Object/Equals/equals_ref.vb new file mode 100644 index 00000000000..1a0c953a4eb --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/equals_ref.vb @@ -0,0 +1,43 @@ +' Visual Basic .NET Document +' Illustrates reference equality with reference types. +Option Strict On + +' +' Define a reference type that does not override Equals. +Public Class Person1 + Private personName As String + + Public Sub New(name As String) + Me.personName = name + End Sub + + Public Overrides Function ToString() As String + Return Me.personName + End Function +End Class + +Module Example0 + Public Sub Main() + Dim person1a As New Person1("John") + Dim person1b As Person1 = person1a + Dim person2 As New Person1(person1a.ToString()) + + Console.WriteLine("Calling Equals:") + Console.WriteLine("person1a and person1b: {0}", person1a.Equals(person1b)) + Console.WriteLine("person1a and person2: {0}", person1a.Equals(person2)) + Console.WriteLine() + + Console.WriteLine("Casting to an Object and calling Equals:") + Console.WriteLine("person1a and person1b: {0}", CObj(person1a).Equals(CObj(person1b))) + Console.WriteLine("person1a and person2: {0}", CObj(person1a).Equals(CObj(person2))) + End Sub +End Module +' The example displays the following output: +' Calling Equals: +' person1a and person1b: True +' person1a and person2: False +' +' Casting to an Object and calling Equals: +' person1a and person1b: True +' person1a and person2: False +' diff --git a/snippets/visualbasic/System/Object/Equals/equals_val1.vb b/snippets/visualbasic/System/Object/Equals/equals_val1.vb new file mode 100644 index 00000000000..5938e4cd2b3 --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/equals_val1.vb @@ -0,0 +1,21 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module ValExample1 + Public Sub Main() + Dim value1 As Byte = 12 + Dim value2 As Integer = 12 + + Dim object1 As Object = value1 + Dim object2 As Object = value2 + + Console.WriteLine("{0} ({1}) = {2} ({3}): {4}", + object1, object1.GetType().Name, + object2, object2.GetType().Name, + object1.Equals(object2)) + End Sub +End Module +' The example displays the following output: +' 12 (Byte) = 12 (Int32): False +' diff --git a/snippets/visualbasic/System/Object/Equals/equals_val2.vb b/snippets/visualbasic/System/Object/Equals/equals_val2.vb new file mode 100644 index 00000000000..dc15482d135 --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/equals_val2.vb @@ -0,0 +1,37 @@ +' Visual Basic .NET Document +Option Strict On + +' +' Define a value type that does not override Equals. +Public Structure Person4 + Private personName As String + + Public Sub New(name As String) + Me.personName = name + End Sub + + Public Overrides Function ToString() As String + Return Me.personName + End Function +End Structure + +Module Example4 + Public Sub Main() + Dim p1 As New Person4("John") + Dim p2 As New Person4("John") + + Console.WriteLine("Calling Equals:") + Console.WriteLine(p1.Equals(p2)) + Console.WriteLine() + + Console.WriteLine("Casting to an Object and calling Equals:") + Console.WriteLine(CObj(p1).Equals(p2)) + End Sub +End Module +' The example displays the following output: +' Calling Equals: +' True +' +' Casting to an Object and calling Equals: +' True +' diff --git a/snippets/visualbasic/System/Object/Equals/equalsoverride.vb b/snippets/visualbasic/System/Object/Equals/equalsoverride.vb new file mode 100644 index 00000000000..82b9d109303 --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/equalsoverride.vb @@ -0,0 +1,39 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Class Person + Private idNumber As String + Private personName As String + + Public Sub New(name As String, id As String) + Me.personName = name + Me.idNumber = id + End Sub + + Public Overrides Function Equals(obj As Object) As Boolean + Dim personObj As Person = TryCast(obj, Person) + If personObj Is Nothing Then + Return False + Else + Return idNumber.Equals(personObj.idNumber) + End If + End Function + + Public Overrides Function GetHashCode() As Integer + Return Me.idNumber.GetHashCode() + End Function +End Class + +Module Example6 + Public Sub Main() + Dim p1 As New Person("John", "63412895") + Dim p2 As New Person("Jack", "63412895") + Console.WriteLine(p1.Equals(p2)) + Console.WriteLine(Object.Equals(p1, p2)) + End Sub +End Module +' The example displays the following output: +' True +' True +' diff --git a/snippets/visualbasic/System/Object/Equals/equalssb1.vb b/snippets/visualbasic/System/Object/Equals/equalssb1.vb new file mode 100644 index 00000000000..8614c04d0ad --- /dev/null +++ b/snippets/visualbasic/System/Object/Equals/equalssb1.vb @@ -0,0 +1,29 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Text + +Module Example5 + Public Sub Main() + Dim sb1 As New StringBuilder("building a string...") + Dim sb2 As New StringBuilder("building a string...") + + Console.WriteLine("sb1.Equals(sb2): {0}", sb1.Equals(sb2)) + Console.WriteLine("CObj(sb1).Equals(sb2): {0}", + CObj(sb1).Equals(sb2)) + Console.WriteLine("Object.Equals(sb1, sb2): {0}", + Object.Equals(sb1, sb2)) + + Console.WriteLine() + Dim sb3 As Object = New StringBuilder("building a string...") + Console.WriteLine("sb3.Equals(sb2): {0}", sb3.Equals(sb2)) + End Sub +End Module +' The example displays the following output: +' sb1.Equals(sb2): True +' CObj(sb1).Equals(sb2): False +' Object.Equals(sb1, sb2): False +' +' sb3.Equals(sb2): False +' diff --git a/snippets/visualbasic/System/Object/Finalize/finalize_safe.vb b/snippets/visualbasic/System/Object/Finalize/finalize_safe.vb new file mode 100644 index 00000000000..d8ac6176fc3 --- /dev/null +++ b/snippets/visualbasic/System/Object/Finalize/finalize_safe.vb @@ -0,0 +1,164 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports Microsoft.Win32.SafeHandles +Imports System.ComponentModel +Imports System.IO +Imports System.Runtime.InteropServices + +Public Class FileAssociationInfo : Implements IDisposable + ' Private variables. + Private ext As String + Private openCmd As String + Private hExtHandle, hAppIdHandle As SafeRegistryHandle + + ' Windows API calls. + Private Declare Unicode Function RegOpenKeyEx Lib "advapi32.dll" _ + Alias "RegOpenKeyExW" (hKey As IntPtr, lpSubKey As String, _ + ulOptions As Integer, samDesired As Integer, _ + ByRef phkResult As IntPtr) As Integer + Private Declare Unicode Function RegQueryValueEx Lib "advapi32.dll" _ + Alias "RegQueryValueExW" (hKey As IntPtr, _ + lpValueName As String, lpReserved As Integer, _ + ByRef lpType As UInteger, lpData As String, _ + ByRef lpcbData As UInteger) As Integer + Private Declare Function RegSetValueEx Lib "advapi32.dll" _ + (hKey As IntPtr, _ + lpValueName As String, _ + reserved As Integer, dwType As UInteger, _ + lpData As String, _ + cpData As Integer) As Integer + Private Declare Function RegCloseKey Lib "advapi32.dll" _ + (hKey As IntPtr) As Integer + + ' Windows API constants. + Private Const HKEY_CLASSES_ROOT As Integer = &h80000000 + Private Const ERROR_SUCCESS As Integer = 0 + + Private Const KEY_QUERY_VALUE As Integer = 1 + Private Const KEY_SET_VALUE As Integer = &h2 + + Private REG_SZ As UInteger = 1 + Private args As String + Private Const MAX_PATH As Integer = 260 + + Public Sub New(fileExtension As String) + Dim retVal As Integer = 0 + Dim lpType As UInteger = 0 + + If Not fileExtension.StartsWith(".") Then + fileExtension = "." + fileExtension + End If + ext = fileExtension + + Dim hExtension As IntPtr = IntPtr.Zero + ' Get the file extension value. + retVal = RegOpenKeyEx(New IntPtr(HKEY_CLASSES_ROOT), fileExtension, 0, + KEY_QUERY_VALUE, hExtension) + if retVal <> ERROR_SUCCESS Then + Throw New Win32Exception(retVal) + End If + ' Instantiate the first SafeRegistryHandle. + hExtHandle = New SafeRegistryHandle(hExtension, True) + + Dim appId As New String(" "c, MAX_PATH) + Dim appIdLength As UInteger = CUInt(appId.Length) + retVal = RegQueryValueEx(hExtHandle.DangerousGetHandle(), String.Empty, _ + 0, lpType, appId, appIdLength) + if retVal <> ERROR_SUCCESS Then + Throw New Win32Exception(retVal) + End If + ' We no longer need the hExtension handle. + hExtHandle.Dispose() + + ' Determine the number of characters without the terminating null. + appId = appId.Substring(0, CInt(appIdLength) \ 2 - 1) + "\shell\open\Command" + + ' Open the application identifier key. + Dim exeName As New string(" "c, MAX_PATH) + Dim exeNameLength As UInteger = CUInt(exeName.Length) + Dim hAppId As IntPtr + retVal = RegOpenKeyEx(New IntPtr(HKEY_CLASSES_ROOT), appId, 0, + KEY_QUERY_VALUE Or KEY_SET_VALUE, hAppId) + If retVal <> ERROR_SUCCESS Then + Throw New Win32Exception(retVal) + End If + + ' Instantiate the second SafeRegistryHandle. + hAppIdHandle = New SafeRegistryHandle(hAppId, True) + + ' Get the executable name for this file type. + Dim exePath As New string(" "c, MAX_PATH) + Dim exePathLength As UInteger = CUInt(exePath.Length) + retVal = RegQueryValueEx(hAppIdHandle.DangerousGetHandle(), _ + String.Empty, 0, lpType, exePath, exePathLength) + If retVal <> ERROR_SUCCESS Then + Throw New Win32Exception(retVal) + End If + ' Determine the number of characters without the terminating null. + exePath = exePath.Substring(0, CInt(exePathLength) \ 2 - 1) + + exePath = Environment.ExpandEnvironmentVariables(exePath) + Dim position As Integer = exePath.IndexOf("%"c) + If position >= 0 Then + args = exePath.Substring(position) + ' Remove command line parameters ('%0', etc.). + exePath = exePath.Substring(0, position).Trim() + End If + openCmd = exePath + End Sub + + Public ReadOnly Property Extension As String + Get + Return ext + End Get + End Property + + Public Property Open As String + Get + Return openCmd + End Get + Set + If hAppIdHandle.IsInvalid Or hAppIdHandle.IsClosed Then + Throw New InvalidOperationException("Cannot write to registry key.") + End If + If Not File.Exists(value) Then + Dim message As String = String.Format("'{0}' does not exist", value) + Throw New FileNotFoundException(message) + End If + Dim cmd As String = value + " %1" + Dim retVal As Integer = RegSetValueEx(hAppIdHandle.DangerousGetHandle(), String.Empty, 0, REG_SZ, cmd, cmd.Length + 1) + If retVal <> ERROR_SUCCESS Then + Throw New Win32Exception(retVal) + End If + End Set + End Property + + Public Sub Dispose() _ + Implements IDisposable.Dispose + Dispose(disposing:=True) + GC.SuppressFinalize(Me) + End Sub + + Protected Sub Dispose(disposing As Boolean) + ' Ordinarily, you release unmanaged resources here, + ' but all are wrapped by safe handles. + + ' Release disposable objects. + If disposing Then + If hExtHandle IsNot Nothing Then hExtHandle.Dispose() + If hAppIdHandle IsNot Nothing Then hAppIdHandle.Dispose() + End If + End Sub +End Class +' + +Module Example + Public Sub Main1() + Dim fa As New FileAssociationInfo(".txt") + Console.WriteLine("{0} files are handled by '{1}'", fa.Extension, fa.Open) + fa.Dispose() + End Sub +End Module + diff --git a/snippets/visualbasic/System/Object/GetHashCode/Project.vbproj b/snippets/visualbasic/System/Object/GetHashCode/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Object/GetHashCode/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Object/GetHashCode/direct1.vb b/snippets/visualbasic/System/Object/GetHashCode/direct1.vb new file mode 100644 index 00000000000..fa15d44fa60 --- /dev/null +++ b/snippets/visualbasic/System/Object/GetHashCode/direct1.vb @@ -0,0 +1,56 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Structure Number + Private n As Integer + + Public Sub New(value As Integer) + n = value + End Sub + + Public ReadOnly Property Value As Integer + Get + Return n + End Get + End Property + + Public Overrides Function Equals(obj As Object) As Boolean + If obj Is Nothing OrElse Not TypeOf obj Is Number Then + Return False + Else + Return n = CType(obj, Number).n + End If + End Function + + Public Overrides Function GetHashCode() As Integer + Return n + End Function + + Public Overrides Function ToString() As String + Return n.ToString() + End Function +End Structure + +Module Example1 + Public Sub Main() + Dim rnd As New Random() + For ctr As Integer = 0 To 9 + Dim randomN As Integer = rnd.Next(Int32.MinValue, Int32.MaxValue) + Dim n As New Number(randomN) + Console.WriteLine("n = {0,12}, hash code = {1,12}", n, n.GetHashCode()) + Next + End Sub +End Module +' The example displays output like the following: +' n = -634398368, hash code = -634398368 +' n = 2136747730, hash code = 2136747730 +' n = -1973417279, hash code = -1973417279 +' n = 1101478715, hash code = 1101478715 +' n = 2078057429, hash code = 2078057429 +' n = -334489950, hash code = -334489950 +' n = -68958230, hash code = -68958230 +' n = -379951485, hash code = -379951485 +' n = -31553685, hash code = -31553685 +' n = 2105429592, hash code = 2105429592 +' diff --git a/snippets/visualbasic/System/Object/GetHashCode/shift1.vb b/snippets/visualbasic/System/Object/GetHashCode/shift1.vb new file mode 100644 index 00000000000..965dbaae22e --- /dev/null +++ b/snippets/visualbasic/System/Object/GetHashCode/shift1.vb @@ -0,0 +1,64 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Structure Point5 + Private x As Integer + Private y As Integer + + Public Sub New(x As Integer, y As Integer) + Me.x = x + Me.y = y + End Sub + + Public Overrides Function Equals(obj As Object) As Boolean + If Not TypeOf obj Is Point5 Then Return False + + Dim p As Point5 = CType(obj, Point5) + Return x = p.x And y = p.y + End Function + + Public Overrides Function GetHashCode() As Integer + Return ShiftAndWrap(x.GetHashCode(), 2) Xor y.GetHashCode() + End Function + + Private Function ShiftAndWrap(value As Integer, positions As Integer) As Integer + positions = positions And &H1F + + ' Save the existing bit pattern, but interpret it as an unsigned integer. + Dim number As UInteger = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0) + ' Preserve the bits to be discarded. + Dim wrapped As UInteger = number >> (32 - positions) + ' Shift and wrap the discarded bits. + Return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) Or wrapped), 0) + End Function +End Structure + +Module Example2 + Public Sub Main() + Dim pt As New Point5(5, 8) + Console.WriteLine(pt.GetHashCode()) + + pt = New Point5(8, 5) + Console.WriteLine(pt.GetHashCode()) + End Sub +End Module +' The example displays the following output: +' 28 +' 37 +' + +Public Class Utility + ' + Public Function ShiftAndWrap(value As Integer, positions As Integer) As Integer + positions = positions And &h1F + + ' Save the existing bit pattern, but interpret it as an unsigned integer. + Dim number As UInteger = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0) + ' Preserve the bits to be discarded. + Dim wrapped AS UInteger = number >> (32 - positions) + ' Shift and wrap the discarded bits. + Return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) Or wrapped), 0) + End Function + ' +End Class diff --git a/snippets/visualbasic/System/Object/GetHashCode/xor1.vb b/snippets/visualbasic/System/Object/GetHashCode/xor1.vb new file mode 100644 index 00000000000..ca429dba04f --- /dev/null +++ b/snippets/visualbasic/System/Object/GetHashCode/xor1.vb @@ -0,0 +1,34 @@ +' +' A type that represents a 2-D point. +Public Structure Point3 + Private x As Integer + Private y As Integer + + Public Sub New(x As Integer, y As Integer) + Me.x = x + Me.y = y + End Sub + + Public Overrides Function Equals(obj As Object) As Boolean + If Not TypeOf obj Is Point3 Then Return False + + Dim p As Point3 = CType(obj, Point3) + Return x = p.x And y = p.y + End Function + + Public Overrides Function GetHashCode() As Integer + Return x Xor y + End Function +End Structure + +Public Module Example3 + Public Sub Main() + Dim pt As New Point3(5, 8) + Console.WriteLine(pt.GetHashCode()) + + pt = New Point3(8, 5) + Console.WriteLine(pt.GetHashCode()) + End Sub +End Module +' + diff --git a/snippets/visualbasic/System/Object/GetHashCode/xor2.vb b/snippets/visualbasic/System/Object/GetHashCode/xor2.vb new file mode 100644 index 00000000000..7a18c7232ed --- /dev/null +++ b/snippets/visualbasic/System/Object/GetHashCode/xor2.vb @@ -0,0 +1,36 @@ +' +Public Structure Point + Private x As Integer + Private y As Integer + + Public Sub New(x As Integer, y As Integer) + Me.x = x + Me.y = y + End Sub + + Public Overrides Function Equals(obj As Object) As Boolean + If Not TypeOf obj Is Point Then Return False + + Dim p As Point = CType(obj, Point) + Return x = p.x And y = p.y + End Function + + Public Overrides Function GetHashCode() As Integer + Return HashCode.Combine(x, y) + End Function +End Structure + +Public Module Example + Public Sub Main() + Dim pt As New Point(5, 8) + Console.WriteLine(pt.GetHashCode()) + + pt = New Point(8, 5) + Console.WriteLine(pt.GetHashCode()) + End Sub +End Module +' The example displays output similar to the following. +' Note: HashCode.Combine results are not stable across .NET versions. +' 185727722 +' -363254492 +' diff --git a/snippets/visualbasic/System/Object/ToString/Project.vbproj b/snippets/visualbasic/System/Object/ToString/Project.vbproj new file mode 100644 index 00000000000..874c98f3477 --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/Project.vbproj @@ -0,0 +1,8 @@ + + + + Library + net10.0 + + + diff --git a/snippets/visualbasic/System/Object/ToString/array1.vb b/snippets/visualbasic/System/Object/ToString/array1.vb new file mode 100644 index 00000000000..22c69d9d017 --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/array1.vb @@ -0,0 +1,19 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Module Example + Public Sub Main() + Dim values() As Integer = { 1, 2, 4, 8, 16, 32, 64, 128 } + Console.WriteLine(values.ToString()) + + Dim list As New List(Of Integer)(values) + Console.WriteLine(list.ToString()) + End Sub +End Module +' The example displays the following output: +' System.Int32[] +' System.Collections.Generic.List`1[System.Int32] +' diff --git a/snippets/visualbasic/System/Object/ToString/customize1.vb b/snippets/visualbasic/System/Object/ToString/customize1.vb new file mode 100644 index 00000000000..3b58a9eaf4e --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/customize1.vb @@ -0,0 +1,43 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic + +Public Class CList(Of T) : Inherits List(Of T) + Public Sub New(capacity As Integer) + MyBase.New(capacity) + End Sub + + Public Sub New(collection As IEnumerable(Of T)) + MyBase.New(collection) + End Sub + + Public Sub New() + MyBase.New() + End Sub + + Public Overrides Function ToString() As String + Dim retVal As String = String.Empty + For Each item As T In Me + If String.IsNullOrEmpty(retval) Then + retVal += item.ToString() + Else + retval += String.Format(", {0}", item) + End If + Next + Return retVal + End Function +End Class + +Module Example1 + Public Sub Main() + Dim list2 As New CList(Of Integer) + list2.Add(1000) + list2.Add(2000) + Console.WriteLine(list2.ToString()) + End Sub +End Module +' The example displays the following output: +' 1000, 2000 +' diff --git a/snippets/visualbasic/System/Object/ToString/customize2.vb b/snippets/visualbasic/System/Object/ToString/customize2.vb new file mode 100644 index 00000000000..53aea4d40a7 --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/customize2.vb @@ -0,0 +1,49 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Collections.Generic +Imports System.Runtime.CompilerServices + +Public Module StringExtensions + + Public Function ToString2(Of T)(l As List(Of T)) As String + Dim retVal As String = "" + For Each item As T In l + retVal += String.Format("{0}{1}", If(String.IsNullOrEmpty(retVal), + "", ", "), + item) + Next + Return If(String.IsNullOrEmpty(retVal), "{}", "{ " + retVal + " }") + End Function + + + Public Function ToString(Of T)(l As List(Of T), fmt As String) As String + Dim retVal As String = String.Empty + For Each item In l + Dim ifmt As IFormattable = TryCast(item, IFormattable) + If ifmt IsNot Nothing Then + retVal += String.Format("{0}{1}", + If(String.IsNullOrEmpty(retval), + "", ", "), ifmt.ToString(fmt, Nothing)) + Else + retVal += ToString2(l) + End If + Next + Return If(String.IsNullOrEmpty(retVal), "{}", "{ " + retVal + " }") + End Function +End Module + +Module Example2 + Public Sub Main() + Dim list As New List(Of Integer) + list.Add(1000) + list.Add(2000) + Console.WriteLine(list.ToString2()) + Console.WriteLine(list.ToString("N0")) + End Sub +End Module +' The example displays the following output: +' { 1000, 2000 } +' { 1,000, 2,000 } +' diff --git a/snippets/visualbasic/System/Object/ToString/tostring1.vb b/snippets/visualbasic/System/Object/ToString/tostring1.vb new file mode 100644 index 00000000000..73942161b36 --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/tostring1.vb @@ -0,0 +1,14 @@ +' Visual Basic .NET Document +Option Strict On + +' +Module Example3 + Public Sub Main() + Dim obj As New Object() + Console.WriteLine(obj.ToString()) + End Sub +End Module +' The example displays the following output: +' System.Object +' + diff --git a/snippets/visualbasic/System/Object/ToString/tostring2.vb b/snippets/visualbasic/System/Object/ToString/tostring2.vb new file mode 100644 index 00000000000..3e39d1172d5 --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/tostring2.vb @@ -0,0 +1,16 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Class Object1 +End Class + +Module Example4 + Public Sub Main() + Dim obj1 As New Object1() + Console.WriteLine(obj1.ToString()) + End Sub +End Module +' The example displays the following output: +' Examples.Object1 +' diff --git a/snippets/visualbasic/System/Object/ToString/tostring3.vb b/snippets/visualbasic/System/Object/ToString/tostring3.vb new file mode 100644 index 00000000000..675ed6076c1 --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/tostring3.vb @@ -0,0 +1,25 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Class Object2 + Private value As Object + + Public Sub New(value As Object) + Me.value = value + End Sub + + Public Overrides Function ToString() As String + Return MyBase.ToString + ": " + value.ToString() + End Function +End Class + +Module Example5 + Public Sub Main() + Dim obj2 As New Object2("a"c) + Console.WriteLine(obj2.ToString()) + End Sub +End Module +' The example displays the following output: +' Object2: a +' diff --git a/snippets/visualbasic/System/Object/ToString/tostringoverload1.vb b/snippets/visualbasic/System/Object/ToString/tostringoverload1.vb new file mode 100644 index 00000000000..298be82f5b9 --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/tostringoverload1.vb @@ -0,0 +1,80 @@ +' Visual Basic .NET Document +Option Strict On + +' +Public Class Automobile + Private _doors As Integer + Private _cylinders As String + Private _year As Integer + Private _model As String + + Public Sub New(model As String, year As Integer, doors As Integer, + cylinders As String) + _model = model + _year = year + _doors = doors + _cylinders = cylinders + End Sub + + Public ReadOnly Property Doors As Integer + Get + Return _doors + End Get + End Property + + Public ReadOnly Property Model As String + Get + Return _model + End Get + End Property + + Public ReadOnly Property Year As Integer + Get + Return _year + End Get + End Property + + Public ReadOnly Property Cylinders As String + Get + Return _cylinders + End Get + End Property + + Public Overrides Function ToString() As String + Return ToString("G") + End Function + + Public Overloads Function ToString(fmt As String) As String + If String.IsNullOrEmpty(fmt) Then fmt = "G" + + Select Case fmt.ToUpperInvariant() + Case "G" + Return String.Format("{0} {1}", _year, _model) + Case "D" + Return String.Format("{0} {1}, {2} dr.", + _year, _model, _doors) + Case "C" + Return String.Format("{0} {1}, {2}", + _year, _model, _cylinders) + Case "A" + Return String.Format("{0} {1}, {2} dr. {3}", + _year, _model, _doors, _cylinders) + Case Else + Dim msg As String = String.Format("'{0}' is an invalid format string", + fmt) + Throw New ArgumentException(msg) + End Select + End Function +End Class + +Module Example6 + Public Sub Main() + Dim auto As New Automobile("Lynx", 2016, 4, "V8") + Console.WriteLine(auto.ToString()) + Console.WriteLine(auto.ToString("A")) + End Sub +End Module +' The example displays the following output: +' 2016 Lynx +' 2016 Lynx, 4 dr. V8 +' diff --git a/snippets/visualbasic/System/Object/ToString/tostringoverload2.vb b/snippets/visualbasic/System/Object/ToString/tostringoverload2.vb new file mode 100644 index 00000000000..3ed2a4649ca --- /dev/null +++ b/snippets/visualbasic/System/Object/ToString/tostringoverload2.vb @@ -0,0 +1,26 @@ +' Visual Basic .NET Document +Option Strict On + +' +Imports System.Globalization + +Module Example7 + Public Sub Main() + Dim cultureNames() As String = {"en-US", "en-GB", "fr-FR", + "hr-HR", "ja-JP"} + Dim value As Decimal = 1603.49D + For Each cultureName In cultureNames + Dim culture As New CultureInfo(cultureName) + Console.WriteLine("{0}: {1}", culture.Name, + value.ToString("C2", culture)) + Next + End Sub +End Module +' The example displays the following output: +' en-US: $1,603.49 +' en-GB: £1,603.49 +' fr-FR: 1 603,49 € +' hr-HR: 1.603,49 kn +' ja-JP: ¥1,603.49 +' + diff --git a/xml/System/IAsyncDisposable.xml b/xml/System/IAsyncDisposable.xml index d4bd32ddecb..63d5c3e59f9 100644 --- a/xml/System/IAsyncDisposable.xml +++ b/xml/System/IAsyncDisposable.xml @@ -45,7 +45,30 @@ Provides a mechanism for releasing unmanaged resources asynchronously. - For more information about this API, see Supplemental API remarks for IAsyncDisposable. + + interface to provide a mechanism for releasing unmanaged resources synchronously. However, in some cases they need to provide an asynchronous mechanism for releasing unmanaged resources in addition to (or instead of) the synchronous one. Providing such a mechanism enables the consumer to perform resource-intensive dispose operations without blocking the main thread of a GUI application for a long time. + +The method of this interface returns a that represents the asynchronous dispose operation. Classes that own unmanaged resources implement this method, and the consumer of these classes calls this method on an object when it is no longer needed. + +The async methods are used in conjunction with the `async` and `await` keywords in C# and Visual Basic. For more information, see [The Task asynchronous programming model in C#](/dotnet/csharp/programming-guide/concepts/async/index) or [Asynchronous Programming with Async and Await (Visual Basic)](/dotnet/visual-basic/programming-guide/concepts/async/index). + +## Use an object that implements IAsyncDisposable + +If your application uses an object that implements `IAsyncDisposable`, you should call the object's implementation when you are finished using it. To make sure resources are released even in case of an exception, put the code that uses the `IAsyncDisposable` object into the [using](/dotnet/csharp/language-reference/keywords/using) statement (in C# beginning from version 8.0) or call the method inside a `finally` clause of the `try`/`finally` statement. For more information about the `try`/`finally` pattern, see [try-finally](/dotnet/csharp/language-reference/keywords/try-finally) (C#) or [Try...Catch...Finally Statement](/dotnet/visual-basic/language-reference/statements/try-catch-finally-statement) (Visual Basic). + +## Implement IAsyncDisposable + +You might implement `IAsyncDisposable` in the following situations: + +- When developing an asynchronous enumerator that owns unmanaged resources. Asynchronous enumerators are used with the C# 8.0 async streams feature. For more information about async streams, see [Tutorial: Generate and consume async streams using C# 8.0 and .NET Core 3.0](/dotnet/csharp/tutorials/generate-consume-asynchronous-stream). +- When your class owns unmanaged resources and releasing them requires a resource-intensive I/O operation, such as flushing the contents of an intermediate buffer into a file or sending a packet over a network to close a connection. + +Use the method to perform whatever cleanup is necessary after using the unmanaged resources, such as freeing, releasing, or resetting the unmanaged resources. For more information, see [Implement a DisposeAsync method](/dotnet/standard/garbage-collection/implementing-disposeasync). + + ]]> + diff --git a/xml/System/IDisposable.xml b/xml/System/IDisposable.xml index e73f3954dd5..7a9df94b03e 100644 --- a/xml/System/IDisposable.xml +++ b/xml/System/IDisposable.xml @@ -47,7 +47,94 @@ Provides a mechanism for releasing unmanaged resources. - For more information about this API, see Supplemental API remarks for IDisposable. + + interface is to release unmanaged resources. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it's not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams. + +Use the method of this interface to explicitly release unmanaged resources in conjunction with the garbage collector. The consumer of an object can call this method when the object is no longer needed. + +> [!WARNING] +> It is a breaking change to add the interface to an existing class. Because pre-existing consumers of your type cannot call , you cannot be certain that unmanaged resources held by your type will be released. + +Because the implementation is called by the consumer of a type when the resources owned by an instance are no longer needed, you should either wrap the managed object in a (the recommended alternative), or you should override to free unmanaged resources in the event that the consumer forgets to call . + +For a detailed discussion about how this interface and the method are used, see the [Garbage Collection](/dotnet/standard/garbage-collection/index) and [Implementing a Dispose Method](/dotnet/standard/garbage-collection/implementing-dispose) topics. + +## Use an object that implements IDisposable + +If your app simply uses an object that implements the interface, you should call the object's implementation when you are finished using it. Depending on your programming language, you can do this in one of two ways: + +- By using a language construct such as the `using` statement in C# and Visual Basic, and the `use` statement or `using` function in F#. +- By wrapping the call to the implementation in a `try`/`finally` block. + +> [!NOTE] +> Documentation for types that implement note that fact and include a reminder to call its implementation. + +### The C#, F#, and Visual Basic Using statement + +If your language supports a construct such as the [using](/dotnet/csharp/language-reference/keywords/using) statement in C#, the [Using](/dotnet/visual-basic/language-reference/statements/using-statement) statement in Visual Basic, or the [use](/dotnet/fsharp/language-reference/resource-management-the-use-keyword) statement in F#, you can use it instead of explicitly calling yourself. The following example uses this approach in defining a `WordCount` class that preserves information about a file and the number of words in it. + +:::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/calling1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/calling1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/IDisposable/Overview/calling1.vb" id="Snippet1"::: + +The `using` statement (`use` expression in F#) is actually a syntactic convenience. At compile time, the language compiler implements the intermediate language (IL) for a `try`/`finally` block. + +For more information about the `using` statement, see the [Using Statement](/dotnet/visual-basic/language-reference/statements/using-statement) or [using Statement](/dotnet/csharp/language-reference/keywords/using-statement) topics. + +### The Try/Finally block + +If your programming language does not support a construct like the `using` statement in C# or Visual Basic, or the `use` statement in F#, or if you prefer not to use it, you can call the implementation from the `finally` block of a `try`/`finally` statement. The following example replaces the `using` block in the previous example with a `try`/`finally` block. + +:::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/calling2.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/calling2.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/IDisposable/Overview/calling2.vb" id="Snippet2"::: + +For more information about the `try`/`finally` pattern, see [Try...Catch...Finally Statement](/dotnet/visual-basic/language-reference/statements/try-catch-finally-statement), [try-finally](/dotnet/csharp/language-reference/keywords/try-finally), [try...finally Expression](/dotnet/fsharp/language-reference/exception-handling/the-try-finally-expression), or [try-finally Statement](/cpp/c-language/try-finally-statement-c). + +## Implement IDisposable + +You should implement if your type uses unmanaged resources directly or if you wish to use disposable resources yourself. The consumers of your type can call your implementation to free resources when the instance is no longer needed. To handle cases in which they fail to call , you should either use a class derived from to wrap the unmanaged resources, or you should override the method for a reference type. In either case, you use the method to perform whatever cleanup is necessary after using the unmanaged resources, such as freeing, releasing, or resetting the unmanaged resources. For more information about implementing , see [the Dispose(bool) method overload](/dotnet/standard/garbage-collection/implementing-dispose.md#the-disposebool-method-overload). + +> [!IMPORTANT] +> If you are defining a base class that uses unmanaged resources and that either has, or is likely to have, subclasses that should be disposed, you should implement the method and provide a second overload of `Dispose`, as discussed in the next section. + +## IDisposable and the inheritance hierarchy + +A base class with subclasses that should be disposable must implement as follows. You should use this pattern whenever you implement on any type that isn't `sealed` (`NotInheritable` in Visual Basic). + +- It should provide one public, non-virtual method and a protected virtual `Dispose(Boolean disposing)` method. +- The method must call `Dispose(true)` and should suppress finalization for performance. +- The base type should not include any finalizers. + +The following code fragment reflects the dispose pattern for base classes. It assumes that your type does not override the method. + +:::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/base1.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/base1.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/IDisposable/Overview/base1.vb" id="Snippet3"::: + +If you do override the method, your class should implement the following pattern. + +:::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/base2.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/base2.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/IDisposable/Overview/base2.vb" id="Snippet5"::: + +Subclasses should implement the disposable pattern as follows: + +- They must override `Dispose(Boolean)` and call the base class `Dispose(Boolean)` implementation. +- They can provide a finalizer if needed. The finalizer must call `Dispose(false)`. + +Note that derived classes do not themselves implement the interface and do not include a parameterless method. They only override the base class `Dispose(Boolean)` method. + +The following code fragment reflects the dispose pattern for derived classes. It assumes that your type does not override the method. + +:::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/derived1.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/derived1.fs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/IDisposable/Overview/derived1.vb" id="Snippet4"::: + + ]]> + interface. diff --git a/xml/System/Int32.xml b/xml/System/Int32.xml index 527e559a9e3..c3413a5b094 100644 --- a/xml/System/Int32.xml +++ b/xml/System/Int32.xml @@ -238,7 +238,75 @@ Represents a 32-bit signed integer. - For more information about this API, see Supplemental API remarks for Int32. + + is an immutable value type that represents signed integers with values that range from negative 2,147,483,648 (which is represented by the constant) through positive 2,147,483,647 (which is represented by the constant). .NET also includes an unsigned 32-bit integer value type, , which represents values that range from 0 to 4,294,967,295. + +## Instantiate an Int32 value + +You can instantiate an value in several ways: + +- You can declare an 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/Int32/Overview/Instantiate1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int32/Overview/Instantiate1.fs" id="Snippet1"::: + :::code language="vb" source="~/snippets/visualbasic/System/Int32/Overview/Instantiate1.vb" id="Snippet1"::: + +- You can assign the value of an integer type whose range is a subset of the type. This is a widening conversion that does not require a cast operator in C# or a conversion method in Visual Basic but does require one in F#. + + :::code language="csharp" source="~/snippets/csharp/System/Int32/Overview/Instantiate1.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int32/Overview/Instantiate1.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Int32/Overview/Instantiate1.vb" id="Snippet4"::: + +- You can assign the value of a numeric type whose range exceeds that of the type. This is a narrowing conversion, so it requires a cast operator in C# or F#, and a conversion method in Visual Basic if `Option Strict` is on. If the numeric 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 performs narrowing conversions to assign several numeric values to variables. + + :::code language="csharp" source="~/snippets/csharp/System/Int32/Overview/Instantiate1.cs" id="Snippet2"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int32/Overview/Instantiate1.fs" id="Snippet2"::: + :::code language="vb" source="~/snippets/visualbasic/System/Int32/Overview/Instantiate1.vb" id="Snippet2"::: + +- You can call a method of the class to convert any supported type to an 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/Convert/ToInt32/toint32_1.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int32/Overview/toint32_1.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Convert/ToInt32/toint32_1.vb" id="Snippet4"::: + +- You can call the or method to convert the string representation of an value to an . 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/Int32/Overview/Instantiate1.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int32/Overview/Instantiate1.fs" id="Snippet3"::: + :::code language="vb" source="~/snippets/visualbasic/System/Int32/Overview/Instantiate1.vb" id="Snippet3"::: + +## Perform operations on Int32 values + +The type supports standard mathematical operations such as addition, subtraction, division, multiplication, 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 an Int32 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).) + +To format an 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 "N" format specifier, you can include group separators and specify the number of decimal digits to appear in the string representation of the number. By using the "X" format specifier, you can represent an value as a hexadecimal string. The following example formats the elements in an array of values in these four ways. + +:::code language="csharp" source="~/snippets/csharp/System/Int32/Overview/Formatting1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Int32/Overview/Formatting1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Int32/Overview/Formatting1.vb" id="Snippet1"::: + +You can also format an 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 integer values. + +:::code language="csharp" source="~/snippets/csharp/System/Int32/Overview/Formatting1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Int32/Overview/Formatting1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Int32/Overview/Formatting1.vb" id="Snippet2"::: + +## Work with non-decimal 32-bit integer values + +In addition to working with individual integers as decimal values, you may want to perform bitwise operations with integer values, or work with the binary or hexadecimal representations of integer values. values are represented in 31 bits, with the thirty-second bit used as a sign bit. Positive values are represented by using sign-and-magnitude representation. Negative values are in two's complement representation. This is important to keep in mind when you perform bitwise operations on values or when you work with individual bits. In order to perform a numeric, Boolean, or comparison operation on any two non-decimal values, both values must use the same representation. + + ]]> + 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. Sample: .NET Core WinForms Formatting Utility (C#) diff --git a/xml/System/Int64.xml b/xml/System/Int64.xml index 7816c22b11f..2cc63ad0077 100644 --- a/xml/System/Int64.xml +++ b/xml/System/Int64.xml @@ -238,7 +238,75 @@ Represents a 64-bit signed integer. - For more information about this API, see Supplemental API remarks for Int64. + + is an immutable value type that represents signed integers with values that range from negative 9,223,372,036,854,775,808 (which is represented by the constant) through positive 9,223,372,036,854,775,807 (which is represented by the constant). .NET also includes an unsigned 64-bit integer value type, , which represents values that range from 0 to 18,446,744,073,709,551,615. + +## Instantiate an Int64 value + +You can instantiate an value in several ways: + +- You can declare an 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/Int64/Overview/instantiate1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int64/Overview/instantiate1.fs" id="Snippet1"::: + :::code language="vb" source="~/snippets/visualbasic/System/Int64/Overview/instantiate1.vb" id="Snippet1"::: + +- You can assign the value of an integral type whose range is a subset of the type. This is a widening conversion that does not require a cast operator in C# or a conversion method in Visual Basic. In F#, only the type can be widened automatically. + + :::code language="csharp" source="~/snippets/csharp/System/Int64/Overview/instantiate1.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int64/Overview/instantiate1.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Int64/Overview/instantiate1.vb" id="Snippet4"::: + +- You can assign the value of a numeric type whose range exceeds that of the type. This is a narrowing conversion, so it requires a cast operator in C# or F# and a conversion method in Visual Basic if `Option Strict` is on. If the numeric 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 performs narrowing conversions to assign several numeric values to variables. + + :::code language="csharp" source="~/snippets/csharp/System/Int64/Overview/instantiate1.cs" id="Snippet2"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int64/Overview/instantiate1.fs" id="Snippet2"::: + :::code language="vb" source="~/snippets/visualbasic/System/Int64/Overview/instantiate1.vb" id="Snippet2"::: + +- You can call a method of the class to convert any supported type to an 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/Convert/ToInt64/toint64_1.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Convert/ToInt64/toint64_1.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Convert/ToInt64/toint64_1.vb" id="Snippet4"::: + +- You can call the or method to convert the string representation of an value to an . 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/Int64/Overview/instantiate1.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Int64/Overview/instantiate1.fs" id="Snippet3"::: + :::code language="vb" source="~/snippets/visualbasic/System/Int64/Overview/instantiate1.vb" id="Snippet3"::: + +## Perform operations on Int64 values + +The type supports standard mathematical operations such as addition, subtraction, division, multiplication, 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 long integers, getting the sign of a number, and rounding a number. + +## Represent an Int64 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).) + +To format an 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 "N" format specifier, you can include group separators and specify the number of decimal digits to appear in the string representation of the number. By using the "X" format specifier, you can represent an value as a hexadecimal string. The following example formats the elements in an array of values in these four ways. + +:::code language="csharp" source="~/snippets/csharp/System/Int64/Overview/formatting1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Convert/ToInt64/formatting1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Int64/Overview/formatting1.vb" id="Snippet1"::: + +You can also format an 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 integer values. + +:::code language="csharp" source="~/snippets/csharp/System/Int64/Overview/formatting1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Convert/ToInt64/formatting1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Int64/Overview/formatting1.vb" id="Snippet2"::: + +## Work with non-decimal 64-bit integer values + +In addition to working with individual long integers as decimal values, you might want to perform bitwise operations or work with the binary or hexadecimal representations of long integer values. values are represented in 63 bits, with the sixty-fourth bit used as a sign bit. Positive values are represented by using sign-and-magnitude representation. Negative values are in two's complement representation. 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. + + ]]> + 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. Sample: .NET Core WinForms Formatting Utility (C#) diff --git a/xml/System/InvalidCastException.xml b/xml/System/InvalidCastException.xml index 5afcd9fd6ea..c4ed1cbfd25 100644 --- a/xml/System/InvalidCastException.xml +++ b/xml/System/InvalidCastException.xml @@ -61,7 +61,107 @@ The exception that is thrown for invalid casting or explicit conversion. - For more information about this API, see Supplemental API remarks for InvalidCastException. + + exception is thrown when the conversion of an instance of one type to another type is not supported. For example, attempting to convert a value to a value throws an exception. It differs from an exception, which is thrown when a conversion of one type to another is supported, but the value of the source type is outside the range of the target type. An exception is caused by developer error and should not be handled in a `try/catch` block. Instead, the cause of the exception should be eliminated. + +For information about conversions supported by the system, see the class. For errors that occur when the destination type can store source type values but is not large enough to store a specific source value, see the exception. + +> [!NOTE] +> In many cases, your language compiler detects that no conversion exists between the source type and the target type and issues a compiler error. + +Some of the conditions under which an attempted conversion throws an exception are discussed in the following sections. + +For an explicit reference conversion to be successful, the source value must be `null`, or the object type referenced by the source argument must be convertible to the destination type by an implicit reference conversion. + +The following intermediate language (IL) instructions throw an exception: + +- `castclass` +- `refanyval` +- `unbox` + + uses the HRESULT `COR_E_INVALIDCAST`, which has the value 0x80004002. + +For a list of initial property values for an instance of , see the constructors. + +## Primitive types and IConvertible + +You directly or indirectly call a primitive type's implementation that does not support a particular conversion. For example, trying to convert a value to a or a value to an throws an exception. The following example calls both the and methods to convert a value to a . In both cases, the method call throws an exception. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidCastException/Overview/iconvertible1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidCastException/Overview/iconvertible1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidCastException/Overview/iconvertible1.vb" id="Snippet2"::: + +Because the conversion is not supported, there is no workaround. + +## The Convert.ChangeType method + +You've called the method to convert an object from one type to another, but one or both types don't implement the interface. + +In most cases, because the conversion is not supported, there is no workaround. In some cases, a possible workaround is to manually assign property values from the source type to similar properties of a the target type. + +## Narrowing conversions and IConvertible implementations + +Narrowing operators define the explicit conversions supported by a type. A casting operator in C# or the `CType` conversion method in Visual Basic (if `Option Strict` is on) is required to perform the conversion. + +However, if neither the source type nor the target type defines an explicit or narrowing conversion between the two types, and the implementation of one or both types doesn't support a conversion from the source type to the target type, an exception is thrown. + +In most cases, because the conversion is not supported, there is no workaround. + +## Downcasting + +You're downcasting, that is, trying to convert an instance of a base type to one of its derived types. In the following example, trying to convert a `Person` object to a `PersonWithID` object fails. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidCastException/Overview/basetoderived1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidCastException/Overview/basetoderived1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidCastException/Overview/basetoderived1.vb" id="Snippet1"::: + +As the example shows, the downcast succeeds only if the `Person` object was created by an upcast from a `PersonWithId` object to a `Person` object, or if the `Person` object is `null`. + +## Conversion from an interface object + +You're attempting to convert an interface object to a type that implements that interface, but the target type is not the same type or a base class of the type from which the interface object was originally derived. The following example throws an exception when it attempts to convert an object to a object. The conversion fails because although the class implements the interface, the object is not related to the class from which the interface object was derived. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidCastException/Overview/Interface1.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidCastException/Overview/Interface1.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidCastException/Overview/Interface1.vb" id="Snippet3"::: + +As the exception message indicates, the conversion would succeed only if the interface object is converted back to an instance of the original type, in this case a . The conversion would also succeed if the interface object is converted to an instance of a base type of the original type. + +## String conversions + +You're trying to convert a value or an object to its string representation by using a casting operator in C#. In the following example, both the attempt to cast a value to a string and the attempt to cast an integer to a string throw an exception. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidCastException/Overview/ToString1.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidCastException/Overview/ToString1.fs" id="Snippet4"::: + +> [!NOTE] +> Using the Visual Basic `CStr` operator to convert a value of a primitive type to a string succeeds. The operation does not throw an exception. + +To successfully convert an instance of any type to its string representation, call its `ToString` method, as the following example does. The `ToString` method is always present, since the method is defined by the class and therefore is either inherited or overridden by all managed types. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidCastException/Overview/ToString2.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidCastException/Overview/ToString2.fs" id="Snippet5"::: + +## Visual Basic 6.0 migration + +You're upgrading a Visual Basic 6.0 application with a call to a custom event in a user control to Visual Basic .NET, and an exception is thrown with the message, "Specified cast is not valid." To eliminate this exception, change the line of code in your form (such as `Form1`) + +```vb +Call UserControl11_MyCustomEvent(UserControl11, New UserControl1.MyCustomEventEventArgs(5)) +``` + +and replace it with the following line of code: + +```vb +Call UserControl11_MyCustomEvent(UserControl11(0), New UserControl1.MyCustomEventEventArgs(5)) +``` + + ]]> + Handling and Throwing Exceptions Type Conversion in .NET diff --git a/xml/System/InvalidOperationException.xml b/xml/System/InvalidOperationException.xml index bce246eb909..a3b545c03fb 100644 --- a/xml/System/InvalidOperationException.xml +++ b/xml/System/InvalidOperationException.xml @@ -61,7 +61,255 @@ The exception that is thrown when a method call is invalid for the object's current state. - For more information about this API, see Supplemental API remarks for InvalidOperationException. + + is used in cases when the failure to invoke a method is caused by reasons other than invalid arguments. Typically, it's thrown when the state of an object cannot support the method call. For example, an exception is thrown by methods such as: + +- if objects of a collection are modified after the enumerator is created. For more information, see [Changing a collection while iterating it](#changing-a-collection-while-iterating-it). +- if the resource set is closed before the method call is made. +- , if the object or objects to be added would result in an incorrectly structured XML document. +- A method that attempts to manipulate the UI from a thread that is not the main or UI thread. + +> [!IMPORTANT] +> Because the exception can be thrown in a wide variety of circumstances, it is important to read the exception message returned by the property. + + uses the HRESULT `COR_E_INVALIDOPERATION`, which has the value 0x80131509. + +For a list of initial property values for an instance of , see the constructors. + +## Common causes of InvalidOperationException exceptions + +The following sections show how some common cases in which in exception is thrown in an app. How you handle the issue depends on the specific situation. Most commonly, however, the exception results from developer error, and the exception can be anticipated and avoided. + +### Updating a UI thread from a non-UI thread + +Often, worker threads are used to perform some background work that involves gathering data to be displayed in an application's user interface. However. most GUI (graphical user interface) application frameworks for .NET, such as Windows Forms and Windows Presentation Foundation (WPF), let you access GUI objects only from the thread that creates and manages the UI (the Main or UI thread). An is thrown when you try to access a UI element from a thread other than the UI thread. The text of the exception message is shown in the following table. + +|Application Type|Message| +|----------------------|-------------| +|WPF app|**The calling thread cannot access this object because a different thread owns it.**| +|UWP app|**The application called an interface that was marshaled for a different thread.**| +|Windows Forms app|**Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on.**| + +UI frameworks for .NET implement a *dispatcher* pattern that includes a method to check whether a call to a member of a UI element is being executed on the UI thread, and other methods to schedule the call on the UI thread: + +- In WPF apps, call the method to determine if a method is running on a non-UI thread. It returns `true` if the method is running on the UI thread and `false` otherwise. Call one of the overloads of the method to schedule the call on the UI thread. +- In UWP apps, check the property to determine if a method is running on a non-UI thread. Call the method to execute a delegate that updates the UI thread. +- In Windows Forms apps, use the property to determine if a method is running on a non-UI thread. Call one of the overloads of the method to execute a delegate that updates the UI thread. + +The following examples illustrate the exception that is thrown when you attempt to update a UI element from a thread other than the thread that created it. Each example requires that you create two controls: + +- A text box control named `textBox1`. In a Windows Forms app, you should set its property to `true`. +- A button control named `threadExampleBtn`. The example provides a handler, `ThreadsExampleBtn_Click`, for the button's `Click` event. + +In each case, the `threadExampleBtn_Click` event handler calls the `DoSomeWork` method twice. The first call runs synchronously and succeeds. But the second call, because it runs asynchronously on a thread pool thread, attempts to update the UI from a non-UI thread. This results in a exception. + +#### WPF apps + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/WPF1/MainWindow.xaml.cs" id="Snippet1"::: + +The following version of the `DoSomeWork` method eliminates the exception in a WPF app. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/WPF2/MainWindowDispatcher.xaml.cs" id="Snippet3"::: + +#### Windows Forms apps + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/WinForms/Form1.cs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form1.vb" id="Snippet2"::: + +The following version of the `DoSomeWork` method eliminates the exception in a Windows Forms app. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/WinForms/Form11.cs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/WinForms/Form11.vb" id="Snippet5"::: + +### Changing a collection while iterating it + +The `foreach` statement in C#, `for...in` in F#, or `For Each` statement in Visual Basic is used to iterate the members of a collection and to read or modify its individual elements. However, it can't be used to add or remove items from the collection. Doing this throws an exception with a message that is similar to, "**Collection was modified; enumeration operation may not execute.**" + +The following example iterates a collection of integers attempts to add the square of each integer to the collection. The example throws an with the first call to the method. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Iterating1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating1.vb" id="Snippet1"::: + +You can eliminate the exception in one of two ways, depending on your application logic: + +- If elements must be added to the collection while iterating it, you can iterate it by index using the `for` (`for..to` in F#) statement instead of `foreach`, `for...in`, or `For Each`. The following example uses the for statement to add the square of numbers in the collection to the collection. + + :::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating2.cs" id="Snippet2"::: + :::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Iterating2.fs" id="Snippet2"::: + :::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating2.vb" id="Snippet2"::: + + Note that you must establish the number of iterations before iterating the collection either by using a counter inside the loop that will exit the loop appropriately, by iterating backward, from `Count` - 1 to 0, or, as the example does, by assigning the number of elements in the array to a variable and using it to establish the upper bound of the loop. Otherwise, if an element is added to the collection on every iteration, an endless loop results. + +- If it is not necessary to add elements to the collection while iterating it, you can store the elements to be added in a temporary collection that you add when iterating the collection has finished. The following example uses this approach to add the square of numbers in a collection to a temporary collection, and then to combine the collections into a single array object. + + :::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Iterating3.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Iterating3.fs" id="Snippet3"::: + :::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Iterating3.vb" id="Snippet3"::: + +### Sorting an array or collection whose objects cannot be compared + +General-purpose sorting methods, such as the method or the method, usually require that at least one of the objects to be sorted implement the or the interface. If not, the collection or array cannot be sorted, and the method throws an exception. The following example defines a `Person` class, stores two `Person` objects in a generic object, and attempts to sort them. As the output from the example shows, the call to the method throws an . + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort1.cs" id="Snippet12"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/List_Sort1.fs" id="Snippet12"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort1.vb" id="Snippet12"::: + +You can eliminate the exception in any of three ways: + +- If you can own the type that you are trying to sort (that is, if you control its source code), you can modify it to implement the or the interface. This requires that you implement either the or the method. Adding an interface implementation to an existing type is not a breaking change. + + The following example uses this approach to provide an implementation for the `Person` class. You can still call the collection or array's general sorting method and, as the output from the example shows, the collection sorts successfully. + + :::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort2.cs" id="Snippet13"::: + :::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/List_Sort2.fs" id="Snippet13"::: + :::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort2.vb" id="Snippet13"::: + +- If you cannot modify the source code for the type you are trying to sort, you can define a special-purpose sorting class that implements the interface. You can call an overload of the `Sort` method that includes an parameter. This approach is especially useful if you want to develop a specialized sorting class that can sort objects based on multiple criteria. + + The following example uses the approach by developing a custom `PersonComparer` class that is used to sort `Person` collections. It then passes an instance of this class to the method. + + :::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort3.cs" id="Snippet14"::: + :::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/List_Sort3.fs" id="Snippet14"::: + :::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort3.vb" id="Snippet14"::: + +- If you cannot modify the source code for the type you are trying to sort, you can create a delegate to perform the sorting. The delegate signature is + + ```vb + Function Comparison(Of T)(x As T, y As T) As Integer + ``` + + ```csharp + int Comparison(T x, T y) + ``` + + The following example uses the approach by defining a `PersonComparison` method that matches the delegate signature. It then passes this delegate to the method. + + :::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/List_Sort4.cs" id="Snippet15"::: + :::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/List_Sort4.fs" id="Snippet15"::: + :::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/List_Sort4.vb" id="Snippet15"::: + +### Casting a Nullable\ that's null to its underlying type + +Attempting to cast a value that is `null` to its underlying type throws an exception and displays the error message, "**Nullable object must have a value.** + +The following example throws an exception when it attempts to iterate an array that includes a `Nullable(Of Integer)` value. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Nullable1.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Nullable1.fs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Nullable1.vb" id="Snippet4"::: + +To prevent the exception: + +- Use the property to select only those elements that are not `null`. +- Call one of the overloads to provide a default value for a `null` value. + +The following example does both to avoid the exception. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Nullable2.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Nullable2.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Nullable2.vb" id="Snippet5"::: + +### Call a System.Linq.Enumerable method on an empty collection + +The , , , , , , , and methods perform operations on a sequence and return a single result. Some overloads of these methods throw an exception when the sequence is empty, while other overloads return `null`. The method also throws an exception when the sequence contains more than one element. + +> [!NOTE] +> Most of the methods that throw an exception are overloads. Be sure that you understand the behavior of the overload that you choose. + +The following table lists the exception messages from the exception objects thrown by calls to some methods. + +|Method|Message| +|------------|-------------| +|`Aggregate`
`Average`
`Last`
`Max`
`Min`|**Sequence contains no elements**| +|`First`|**Sequence contains no matching element**| +|`Single`
`SingleOrDefault`|**Sequence contains more than one matching element**| + +How you eliminate or handle the exception depends on your application's assumptions and on the particular method you call. + +- When you deliberately call one of these methods without checking for an empty sequence, you are assuming that the sequence is not empty, and that an empty sequence is an unexpected occurrence. In this case, catching or rethrowing the exception is appropriate. + +- If your failure to check for an empty sequence was inadvertent, you can call one of the overloads of the overload to determine whether a sequence contains any elements. + + > [!TIP] + > Calling the method before generating a sequence can improve performance if the data to be processed might contain a large number of elements or if operation that generates the sequence is expensive. + +- If you've called a method such as , , or , you can substitute an alternate method, such as , , or , that returns a default value instead of a member of the sequence. + +The examples provide additional detail. + +The following example uses the method to compute the average of a sequence whose values are greater than 4. Since no values from the original array exceed 4, no values are included in the sequence, and the method throws an exception. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable1.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Enumerable1.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable1.vb" id="Snippet6"::: + +The exception can be eliminated by calling the method to determine whether the sequence contains any elements before calling the method that processes the sequence, as the following example shows. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable2.cs" id="Snippet7"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Enumerable2.fs" id="Snippet7"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable2.vb" id="Snippet7"::: + +The method returns the first item in a sequence or the first element in a sequence that satisfies a specified condition. If the sequence is empty and therefore does not have a first element, it throws an exception. + +In the following example, the method throws an exception because the dbQueryResults array doesn't contain an element greater than 4. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable3.cs" id="Snippet8"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Enumerable3.fs" id="Snippet8"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable3.vb" id="Snippet8"::: + +You can call the method instead of to return a specified or default value. If the method does not find a first element in the sequence, it returns the default value for that data type. The default value is `null` for a reference type, zero for a numeric data type, and for the type. + +> [!NOTE] +> Interpreting the value returned by the method is often complicated by the fact that the default value of the type can be a valid value in the sequence. In this case, you an call the method to determine whether the sequence has valid members before calling the method. + +The following example calls the method to prevent the exception thrown in the previous example. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable4.cs" id="Snippet9"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Enumerable4.fs" id="Snippet9"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable4.vb" id="Snippet9"::: + +### Call Enumerable.Single or Enumerable.SingleOrDefault on a sequence without one element + +The method returns the only element of a sequence, or the only element of a sequence that meets a specified condition. If there are no elements in the sequence, or if there is more than one element , the method throws an exception. + +You can use the method to return a default value instead of throwing an exception when the sequence contains no elements. However, the method still throws an exception when the sequence contains more than one element. + +The following table lists the exception messages from the exception objects thrown by calls to the and methods. + +| Method | Message | +|-----------------------------------|------------------------------------------------------| +| `Single` | **Sequence contains no matching element** | +| `Single`
`SingleOrDefault` | **Sequence contains more than one matching element** | + +In the following example, the call to the method throws an exception because the sequence doesn't have an element greater than 4. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable5.cs" id="Snippet10"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Enumerable5.fs" id="Snippet10"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable5.vb" id="Snippet10"::: + +The following example attempts to prevent the exception thrown when a sequence is empty by instead calling the method. However, because this sequence returns multiple elements whose value is greater than 2, it also throws an exception. + +:::code language="csharp" source="~/snippets/csharp/System/InvalidOperationException/Overview/Other/Enumerable6.cs" id="Snippet11"::: +:::code language="fsharp" source="~/snippets/fsharp/System/InvalidOperationException/Overview/Enumerable6.fs" id="Snippet11"::: +:::code language="vb" source="~/snippets/visualbasic/System/InvalidOperationException/Overview/Other/Enumerable6.vb" id="Snippet11"::: + +Calling the method assumes that either a sequence or the sequence that meets specified criteria contains only one element. assumes a sequence with zero or one result, but no more. If this assumption is a deliberate one on your part and these conditions are not met, rethrowing or catching the resulting is appropriate. Otherwise, or if you expect that invalid conditions will occur with some frequency, you should consider using some other method, such as or . + +### Dynamic cross-application domain field access + +The common intermediate language (CIL) instruction throws an exception if the object containing the field whose address you are trying to retrieve is not within the application domain in which your code is executing. The address of a field can only be accessed from the application domain in which it resides. + +## Throw an InvalidOperationException exception + +You should throw an exception only when the state of your object for some reason does not support a particular method call. That is, the method call is valid in some circumstances or contexts, but is invalid in others. + +If the method invocation failure is due to invalid arguments, then or one of its derived classes, or , should be thrown instead. + + ]]>
+
diff --git a/xml/System/Math.xml b/xml/System/Math.xml index 38ae1629db5..55d37bb5b38 100644 --- a/xml/System/Math.xml +++ b/xml/System/Math.xml @@ -5951,7 +5951,7 @@ The following table indicates the return value when various values or ranges of | x | y | Return value | | ------------------------------ | ---------------------------------------- | ---------------------------------------- | | Any value except `NaN` | ±0 | 1 | -| `NaN` | ±0 | 1 (`NaN` on .NET Framework)\* | +| `NaN` | ±0 | 1\* | | `NaN` | Any value except 0 | `NaN`\* | | ±0 | < 0 and an odd integer | `NegativeInfinity` or `PositiveInfinity` | | ±0 | `NegativeInfinity` | `PositiveInfinity` | @@ -5959,7 +5959,7 @@ The following table indicates the return value when various values or ranges of | ±0 | > 0 and an odd integer | ±0 | | -1 | `NegativeInfinity` or `PositiveInfinity` | 1 | | +1 | Any value except `NaN` | 1 | -| +1 | `NaN` | 1 (`NaN` on .NET Framework)\* | +| +1 | `NaN` | 1\* | | Any value except 1 | `NaN` | `NaN`\* | | -1 < x < 1 | `PositiveInfinity` | +0 | | < -1 or > 1 | `PositiveInfinity` | `PositiveInfinity` | diff --git a/xml/System/MathF.xml b/xml/System/MathF.xml index 1516d87f11d..197a38951c4 100644 --- a/xml/System/MathF.xml +++ b/xml/System/MathF.xml @@ -1887,7 +1887,7 @@ The following table indicates the return value when various values or ranges of | x | y | Return value | | ------------------------------ | ---------------------------------------- | ---------------------------------------- | | Any value except `NaN` | ±0 | 1 | -| `NaN` | ±0 | 1 (`NaN` on .NET Framework)\* | +| `NaN` | ±0 | 1\* | | `NaN` | Any value except 0 | `NaN`\* | | ±0 | < 0 and an odd integer | `NegativeInfinity` or `PositiveInfinity` | | ±0 | `NegativeInfinity` | `PositiveInfinity` | @@ -1895,7 +1895,7 @@ The following table indicates the return value when various values or ranges of | ±0 | > 0 and an odd integer | ±0 | | -1 | `NegativeInfinity` or `PositiveInfinity` | 1 | | +1 | Any value except `NaN` | 1 | -| +1 | `NaN` | 1 (`NaN` on .NET Framework)\* | +| +1 | `NaN` | 1\* | | Any value except 1 | `NaN` | `NaN`\* | | -1 < x < 1 | `PositiveInfinity` | +0 | | < -1 or > 1 | `PositiveInfinity` | `PositiveInfinity` | diff --git a/xml/System/MethodAccessException.xml b/xml/System/MethodAccessException.xml index bd3db2505e7..2e0536c6b09 100644 --- a/xml/System/MethodAccessException.xml +++ b/xml/System/MethodAccessException.xml @@ -58,9 +58,8 @@ ## Remarks - This exception is thrown in situations such as the following: +This exception is thrown in situations such as the following: -- A private, protected, or internal method that would not be accessible from normal compiled code is accessed from partially trusted code by using reflection. - A security-critical method is accessed from transparent code. - The access level of a method in a class library has changed, and one or more assemblies that reference the library have not been recompiled. diff --git a/xml/System/MidpointRounding.xml b/xml/System/MidpointRounding.xml index c6f27963387..5d3d5d0f3ca 100644 --- a/xml/System/MidpointRounding.xml +++ b/xml/System/MidpointRounding.xml @@ -59,7 +59,62 @@ Specifies the strategy that mathematical rounding methods should use to round a number. - For more information about this API, see Supplemental API remarks for MidpointRounding. + + enumeration with appropriate overloads of , , and to provide more control of the rounding process. + +There are two overall rounding strategies—*round to nearest* and *directed rounding*—and each enumeration field participates in exactly one of these strategies. + +## Round to nearest + +Fields: + +- +- + +A round-to-nearest operation takes an original number with an implicit or specified precision; examines the next digit, which is at that precision plus one; and returns the nearest number with the same precision as the original number. For positive numbers, if the next digit is from 0 through 4, the nearest number is toward negative infinity. If the next digit is from 6 through 9, the nearest number is toward positive infinity. For negative numbers, if the next digit is from 0 through 4, the nearest number is toward positive infinity. If the next digit is from 6 through 9, the nearest number is toward negative infinity. + +If the next digit is from 0 through 4 or 6 through 9, the `MidpointRounding.AwayFromZero` and `MidpointRounding.ToEven` do not affect the result of the rounding operation. However, if the next digit is 5, which is the midpoint between two possible results, and all remaining digits are zero or there are no remaining digits, the nearest number is ambiguous. In this case, the round-to-nearest modes in `MidpointRounding` enable you to specify whether the rounding operation returns the nearest number away from zero or the nearest even number. + +The following table demonstrates the results of rounding some negative and positive numbers in conjunction with round-to-nearest modes. The precision used to round the numbers is zero, which means the number after the decimal point affects the rounding operation. For example, for the number -2.5, the digit after the decimal point is 5. Because that digit is the midpoint, you can use a `MidpointRounding` value to determine the result of rounding. If `AwayFromZero` is specified, -3 is returned because it is the nearest number away from zero with a precision of zero. If `ToEven` is specified, -2 is returned because it is the nearest even number with a precision of zero. + +| Original number | AwayFromZero | ToEven | +|-----------------|--------------|--------| +| 3.5 | 4 | 4 | +| 2.8 | 3 | 3 | +| 2.5 | 3 | 2 | +| 2.1 | 2 | 2 | +| -2.1 | -2 | -2 | +| -2.5 | -3 | -2 | +| -2.8 | -3 | -3 | +| -3.5 | -4 | -4 | + +## Directed rounding + +Fields: + +- +- +- + +A directed-rounding operation takes an original number with an implicit or specified precision and returns the next closest number in a specific direction with the same precision as the original number. Directed modes on `MidpointRounding` control toward which predefined number the rounding is performed. + +The following table demonstrates the results of rounding some negative and positive numbers in conjunction with directed-rounding modes. The precision used to round the numbers is zero, which means the number before the decimal point is affected by the rounding operation. + +| Original number | ToNegativeInfinity | ToPositiveInfinity | ToZero | +|-----------------|--------------------|--------------------|--------| +| 3.5 | 3 | 4 | 3 | +| 2.8 | 2 | 3 | 2 | +| 2.5 | 2 | 3 | 2 | +| 2.1 | 2 | 3 | 2 | +| -2.1 | -3 | -2 | -2 | +| -2.5 | -3 | -2 | -2 | +| -2.8 | -3 | -2 | -2 | +| -3.5 | -4 | -3 | -3 | + + ]]> + method in conjunction with the `MidpointRounding` enumeration: diff --git a/xml/System/NotImplementedException.xml b/xml/System/NotImplementedException.xml index 625f1b3ba36..a7fde733ce5 100644 --- a/xml/System/NotImplementedException.xml +++ b/xml/System/NotImplementedException.xml @@ -61,7 +61,36 @@ The exception that is thrown when a requested method or operation is not implemented. - For more information about this API, see Supplemental API remarks for NotImplementedException. + + exception is thrown when a particular method, get accessor, or set accessor is present as a member of a type but is not implemented. + + uses the default implementation, which supports reference equality. For a list of initial values for an instance of , see the constructors. + +## Throw the exception + +You might choose to throw a exception in properties or methods in your own types when a member is still in development and will only be implemented later in production code. + +## Handle the exception + +The exception indicates that the method or property that you are attempting to invoke has no implementation and therefore provides no functionality. As a result, you should not handle this error in a `try/catch` block. Instead, you should remove the member invocation from your code. You can include a call to the member when it is implemented in the production version of a library. + +In some cases, a exception might not be used to indicate functionality that is still in development in a preproduction library. However, this still indicates that the functionality is unavailable, and you should remove the member invocation from your code. + +## NotImplementedException and other exception types + +.NET also includes two other exception types, and , that indicate that no implementation exists for a particular member of a type. You should throw one of these instead of a exception under the following conditions: + +- Throw a exception on platforms on which the functionality is not supported if you've designed a type with one or more members that are available on some platforms or versions but not others. +- Throw a exception if the implementation of an interface member or an override to an abstract base class method is not possible. + + For example, the method throws a exception because no meaningful conversion between a date and time and a 32-bit signed integer exists. The method must be present in this case because the class implements the interface. + +You should also throw a exception if you've implemented an abstract base class and add a new member to it that must be overridden by derived classes. In that case, making the member abstract causes existing subclasses to fail to load. + + ]]> + The exception that is thrown when an invoked method is not supported, or when there is an attempt to read, seek, or write to a stream that does not support the invoked functionality. - For more information about this API, see Supplemental API remarks for NotSupportedException. + + indicates that no implementation exists for an invoked method or property. + + uses the HRESULT `COR_E_NOTSUPPORTED`, which has the value 0x80131515. + +For a list of initial property values for an instance of , see the constructors. + +## Throw a NotSupportedException exception + +You might consider throwing a exception in the following cases: + +- You're implementing a general-purpose interface, and some of the methods have no meaningful implementation. For example, if you're creating a date and time type that implements the interface, you would throw a exception for most of the conversions. + +- You've inherited from an abstract class that requires that you override some methods. However, you're only prepared to provide an implementation for a subset of these. For the methods that you decide not to implement, you can choose to throw a . + +- You're defining a general-purpose type with a state that enables operations conditionally. For example, your type can be either read-only or read-write. In that case: + + - If the object is read-only, attempting to assign values to the properties of an instance or call methods that modify instance state should throw a exception. + + - You should implement a property that returns a value that indicates whether particular functionality is available. For example, for a type that can be either read-only or read-write, you could implement a `IsReadOnly` property that indicates whether the set of read-write methods are available or unavailable. + +## Handle a NotSupportedException exception + +The exception indicates that a method has no implementation and that you should not call it. You should not handle the exception. Instead, what you should do depends on the cause of the exception: whether an implementation is completely absent, or the member invocation is inconsistent with the purpose of an object (such as a call to the method on a read-only object). + +**An implementation has not been provided because the operation cannot be performed in a meaningful way.** +This is a common exception when you are calling methods on an object that provides implementations for the methods of an abstract base class, or that implements a general-purpose interface, and the method has no meaningful implementation. + +For example, the class implements the interface, which means that it must include a method to convert every primitive type to every other primitive type. Many of those conversions, however, are not possible. As a result, a call to the method, for instance, throws a exception because there is no possible conversion between a and a value. + +To eliminate the exception, you should eliminate the method call. + +**The method call is not supported given the state of the object.** +You're attempting to invoke a member whose functionality is unavailable because of the object's state. You can eliminate the exception in one of three ways: + +- You know the state of the object in advance, but you've invoked an unsupported method or property. In this case, the member invocation is an error, and you can eliminate it. + +- You know the state of the object in advance (usually because your code has instantiated it), but the object is mis-configured. The following example illustrates this issue. It creates a read-only object and then attempts to write to it. + + :::code language="csharp" source="~/snippets/csharp/System/NotSupportedException/Overview/BadState1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/NotSupportedException/Overview/BadState1.fs" id="Snippet1"::: + :::code language="vb" source="~/snippets/visualbasic/System/NotSupportedException/Overview/BadState1.vb" id="Snippet1"::: + + You can eliminate the exception by ensuring that the instantiated object supports the functionality you intend. The following example addresses the problem of the read-only object by providing the correct arguments to the constructor. + +- You don't know the state of the object in advance, and the object doesn't support a particular operation. In most cases, the object should include a property or method that indicates whether it supports a particular set of operations. You can eliminate the exception by checking the value of the object and invoking the member only if appropriate. + + The following example defines a `DetectEncoding` method that throws a exception when it attempts to read from the beginning of a stream that does not support read access. + + :::code language="csharp" source="~/snippets/csharp/System/NotSupportedException/Overview/TestProp1.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/NotSupportedException/Overview/TestProp1.fs" id="Snippet3"::: + :::code language="vb" source="~/snippets/visualbasic/System/NotSupportedException/Overview/TestProp1.vb" id="Snippet3"::: + + You can eliminate the exception by examining the value of the property and exiting the method if the stream is read-only. + + :::code language="csharp" source="~/snippets/csharp/System/NotSupportedException/Overview/TestProp2.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/NotSupportedException/Overview/TestProp2.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/NotSupportedException/Overview/TestProp2.vb" id="Snippet4"::: + +## Related exception types + +The exception is closely related to two other exception types: + +- + + This exception is thrown when a method could be implemented but is not, either because the member will be implemented in a later version, the member is not available on a particular platform, or the member belongs to an abstract class and a derived class must provide an implementation. + +- + + This exception is thrown in scenarios in which it is generally sometimes possible for the object to perform the requested operation, and the object state determines whether the operation can be performed. + + ]]> + Handling and throwing exceptions in .NET diff --git a/xml/System/Nullable.xml b/xml/System/Nullable.xml index 90b1076b08b..1f7da23dea5 100644 --- a/xml/System/Nullable.xml +++ b/xml/System/Nullable.xml @@ -48,7 +48,25 @@ Supports a value type that can be assigned . This class cannot be inherited. - For more information about this API, see Supplemental API remarks for Nullable. + + class supports value types that can be assigned `null`. + +A type is said to be nullable if it can be assigned a value or can be assigned `null`, which means the type has no value whatsoever. By default, all reference types, such as , are nullable, but all value types, such as , are not. + +In C# and Visual Basic, you mark a value type as nullable by using the `?` notation after the value type. For example, `int?` in C# or `Integer?` in Visual Basic declares an integer value type that can be assigned `null`. + +The class provides complementary support for the structure. The class supports obtaining the underlying type of a nullable type, and comparison and equality operations on pairs of nullable types whose underlying value type does not support generic comparison and equality operations. + +## Boxing and unboxing + +When a nullable type is boxed, the common language runtime automatically boxes the underlying value of the object, not the object itself. That is, if the property is `true`, the contents of the property is boxed. + +If the `HasValue` property of a nullable type is `false`, the result of the boxing operation is `null`. When the underlying value of a nullable type is unboxed, the common language runtime creates a new structure initialized to the underlying value. + + ]]> + Nullable Types (C# Programming Guide) Nullable Value Types (Visual Basic) diff --git a/xml/System/Nullable`1.xml b/xml/System/Nullable`1.xml index 439cc11c1dc..a44172cb5e2 100644 --- a/xml/System/Nullable`1.xml +++ b/xml/System/Nullable`1.xml @@ -58,7 +58,35 @@ The underlying value type of the generic type. Represents a value type that can be assigned . - For more information about this API, see Supplemental API remarks for Nullable<T>. + + class represents a value type that can be assigned `null`. + +A type is said to be nullable if it can be assigned a value or can be assigned `null`, which means the type has no value whatsoever. By default, all reference types, such as , are nullable, but all value types, such as , are not. + +In C# and Visual Basic, you mark a value type as nullable by using the `?` notation after the value type. For example, `int?` in C# or `Integer?` in Visual Basic declares an integer value type that can be assigned `null`. + +The structure supports using only a value type as a nullable type because reference types are nullable by design. + +The class provides complementary support for the structure. The class supports obtaining the underlying type of a nullable type, and comparison and equality operations on pairs of nullable types whose underlying value type does not support generic comparison and equality operations. + +## Fundamental properties + +The two fundamental members of the structure are the and properties. If the property for a object is `true`, the value of the object can be accessed with the property. If the property is `false`, the value of the object is undefined and an attempt to access the property throws an . + +## Boxing and unboxing + +When a nullable type is boxed, the common language runtime automatically boxes the underlying value of the object, not the object itself. That is, if the property is `true`, the contents of the property is boxed. When the underlying value of a nullable type is unboxed, the common language runtime creates a new structure initialized to the underlying value. + +If the `HasValue` property of a nullable type is `false`, the result of a boxing operation is `null`. Consequently, if a boxed nullable type is passed to a method that expects an object argument, that method must be prepared to handle the case where the argument is `null`. When `null` is unboxed into a nullable type, the common language runtime creates a new structure and initializes its `HasValue` property to `false`. + +## Windows runtime components + +You can include a type as a member of a structure exported in a WinMD library. + + ]]> + Supports all classes in the .NET class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all .NET classes; it is the root of the type hierarchy. - For more information about this API, see Supplemental API remarks for Object. + + class is the ultimate base class of all .NET classes; it is the root of the type hierarchy. + +Because all classes in .NET are derived from , every method defined in the class is available in all objects in the system. Derived classes can and do override some of these methods, including: + +- : Supports comparisons between objects. +- : Performs cleanup operations before an object is automatically reclaimed. +- : Generates a number corresponding to the value of the object to support the use of a hash table. +- : Manufactures a human-readable text string that describes an instance of the class. + +Languages typically don't require a class to declare inheritance from because the inheritance is implicit. + +## Performance considerations + +If you're designing a class, such as a collection, that must handle any type of object, you can create class members that accept instances of the class. However, the process of boxing and unboxing a type carries a performance cost. If you know your new class will frequently handle certain value types you can use one of two tactics to minimize the cost of boxing. + +- Create a general method that accepts an type, and a set of type-specific method overloads that accept each value type you expect your class to frequently handle. If a type-specific method exists that accepts the calling parameter type, no boxing occurs and the type-specific method is invoked. If there is no method argument that matches the calling parameter type, the parameter is boxed and the general method is invoked. +- Design your type and its members to use [generics](/dotnet/standard/generics). The common language runtime creates a closed generic type when you create an instance of your class and specify a generic type argument. The generic method is type-specific and can be invoked without boxing the calling parameter. + +Although it's sometimes necessary to develop general purpose classes that accept and return types, you can improve performance by also providing a type-specific class to handle a frequently used type. For example, providing a class that is specific to setting and getting Boolean values eliminates the cost of boxing and unboxing Boolean values. + + ]]> + class and overrides many of the virtual methods of the class. In addition, the example shows how to call many of the static and instance methods of the class. @@ -165,7 +189,154 @@ The following example defines a Point type derived from the Determines whether the specified object is equal to the current object. if the specified object is equal to the current object; otherwise, . - For more information about this API, see Supplemental API remarks for Object.Equals. + + method. + +The type of comparison between the current instance and the `obj` parameter depends on whether the current instance is a reference type or a value type. + +- If the current instance is a reference type, the method tests for reference equality, and a call to the method is equivalent to a call to the method. Reference equality means that the object variables that are compared refer to the same object. The following example illustrates the result of such a comparison. It defines a `Person` class, which is a reference type, and calls the `Person` class constructor to instantiate two new `Person` objects, `person1a` and `person2`, which have the same value. It also assigns `person1a` to another object variable, `person1b`. As the output from the example shows, `person1a` and `person1b` are equal because they reference the same object. However, `person1a` and `person2` are not equal, although they have the same value. + + :::code language="csharp" source="~/snippets/csharp/System/Object/Equals/equals_ref.cs" id="Snippet2"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Object/Equals/equals_ref.fs" id="Snippet2"::: + :::code language="vb" source="~/snippets/visualbasic/System/Object/Equals/equals_ref.vb" id="Snippet2"::: + +- If the current instance is a value type, the method tests for value equality. Value equality means the following: + + - The two objects are of the same type. As the following example shows, a object that has a value of 12 does not equal an object that has a value of 12, because the two objects have different runtime types. + + :::code language="csharp" source="~/snippets/csharp/System/Object/Equals/equals_val1.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Object/Equals/equals_val1.fs" id="Snippet3"::: + :::code language="vb" source="~/snippets/visualbasic/System/Object/Equals/equals_val1.vb" id="Snippet3"::: + + - The values of the public and private fields of the two objects are equal. The following example tests for value equality. It defines a `Person` structure, which is a value type, and calls the `Person` class constructor to instantiate two new `Person` objects, `person1` and `person2`, which have the same value. As the output from the example shows, although the two object variables refer to different objects, `person1` and `person2` are equal because they have the same value for the private `personName` field. + + :::code language="csharp" source="~/snippets/csharp/System/Object/Equals/equals_val2.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Object/Equals/equals_val2.fs" id="Snippet4"::: + :::code language="vb" source="~/snippets/visualbasic/System/Object/Equals/equals_val2.vb" id="Snippet4"::: + +Because the class is the base class for all types in .NET, the method provides the default equality comparison for all other types. However, types often override the method to implement value equality. For more information, see the Notes for Callers and Notes for Inheritors sections. + +## Notes for the Windows Runtime + +When you call the method overload on a class in the Windows Runtime, it provides the default behavior for classes that don't override . This is part of the support that .NET provides for the Windows Runtime (see [.NET Support for Windows Store Apps and Windows Runtime](/dotnet/standard/cross-platform/support-for-windows-store-apps-and-windows-runtime)). Classes in the Windows Runtime don't inherit , and currently don't implement an method. However, they appear to have , , and methods when you use them in your C# or Visual Basic code, and .NET provides the default behavior for these methods. + +> [!NOTE] +> Windows Runtime classes that are written in C# or Visual Basic can override the method overload. + +## Notes for callers + +Derived classes frequently override the method to implement value equality. In addition, types also frequently provide an additional strongly typed overload to the `Equals` method, typically by implementing the interface. When you call the `Equals` method to test for equality, you should know whether the current instance overrides and understand how a particular call to an `Equals` method is resolved. Otherwise, you may be performing a test for equality that is different from what you intended, and the method may return an unexpected value. + +The following example provides an illustration. It instantiates three objects with identical strings, and then makes four calls to `Equals` methods. The first method call returns `true`, and the remaining three return `false`. + +:::code language="csharp" source="~/snippets/csharp/System/Object/Equals/equalssb1.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/Equals/equalssb1.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/Equals/equalssb1.vb" id="Snippet5"::: + +In the first case, the strongly typed method overload, which tests for value equality, is called. Because the strings assigned to the two objects are equal, the method returns `true`. However, does not override . Because of this, when the object is cast to an , when a instance is assigned to a variable of type , and when the method is passed two objects, the default method is called. Because is a reference type, this is equivalent to passing the two objects to the method. Although all three objects contain identical strings, they refer to three distinct objects. As a result, these three method calls return `false`. + +You can compare the current object to another object for reference equality by calling the method. In Visual Basic, you can also use the `is` keyword (for example, `If Me Is otherObject Then ...`). + +## Notes for inheritors + +When you define your own type, that type inherits the functionality defined by the `Equals` method of its base type. The following table lists the default implementation of the `Equals` method for the major categories of types in .NET. + +|Type category|Equality defined by|Comments| +|-------------------|-------------------------|--------------| +|Class derived directly from ||Reference equality; equivalent to calling .| +|Structure||Value equality; either direct byte-by-byte comparison or field-by-field comparison using reflection.| +|Enumeration||Values must have the same enumeration type and the same underlying value.| +|Delegate||Delegates must have the same type with identical invocation lists.| +|Interface||Reference equality.| + +For a value type, you should always override , because tests for equality that rely on reflection offer poor performance. You can also override the default implementation of for reference types to test for value equality instead of reference equality and to define the precise meaning of value equality. Such implementations of return `true` if the two objects have the same value, even if they are not the same instance. The type's implementer decides what constitutes an object's value, but it is typically some or all the data stored in the instance variables of the object. For example, the value of a object is based on the characters of the string; the method overrides the method to return `true` for any two string instances that contain the same characters in the same order. + +The following example shows how to override the method to test for value equality. It overrides the method for the `Person` class. If `Person` accepted its base class implementation of equality, two `Person` objects would be equal only if they referenced a single object. However, in this case, two `Person` objects are equal if they have the same value for the `Person.Id` property. + +:::code language="csharp" source="~/snippets/csharp/System/Object/Equals/equalsoverride.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/Equals/equalsoverride.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/Equals/equalsoverride.vb" id="Snippet6"::: + +In addition to overriding , you can implement the interface to provide a strongly typed test for equality. + +The following statements must be true for all implementations of the method. In the list, `x`, `y`, and `z` represent object references that are not **null**. + +- `x.Equals(x)` returns `true`. + +- `x.Equals(y)` returns the same value as `y.Equals(x)`. + +- `x.Equals(y)` returns `true` if both `x` and `y` are `NaN`. + +- If `(x.Equals(y) && y.Equals(z))` returns `true`, then `x.Equals(z)` returns `true`. + +- Successive calls to `x.Equals(y)` return the same value as long as the objects referenced by `x` and `y` are not modified. + +- `x.Equals(null)` returns `false`. + +Implementations of must not throw exceptions; they should always return a value. For example, if `obj` is `null`, the method should return `false` instead of throwing an . + +Follow these guidelines when overriding : + +- Types that implement must override . + +- Types that override must also override ; otherwise, hash tables might not work correctly. + +- You should consider implementing the interface to support strongly typed tests for equality. Your implementation should return results that are consistent with . + +- If your programming language supports operator overloading and you overload the equality operator for a given type, you must also override the method to return the same result as the equality operator. This helps ensure that class library code that uses (such as and ) behaves in a manner that is consistent with the way the equality operator is used by application code. + +### Guidelines for reference types + +The following guidelines apply to overriding for a reference type: + +- Consider overriding if the semantics of the type are based on the fact that the type represents some value(s). + +- Most reference types must not overload the equality operator, even if they override . However, if you are implementing a reference type that is intended to have value semantics, such as a complex number type, you must override the equality operator. + +- You should not override on a mutable reference type. This is because overriding requires that you also override the method, as discussed in the previous section. This means that the hash code of an instance of a mutable reference type can change during its lifetime, which can cause the object to be lost in a hash table. + +### Guidelines for value types + +The following guidelines apply to overriding for a value type: + +- If you are defining a value type that includes one or more fields whose values are reference types, you should override . The implementation provided by performs a byte-by-byte comparison for value types whose fields are all value types, but it uses reflection to perform a field-by-field comparison of value types whose fields include reference types. + +- If you override and your development language supports operator overloading, you must overload the equality operator. + +- You should implement the interface. Calling the strongly typed method avoids boxing the `obj` argument. + +## Examples + +The following example shows a `Point` class that overrides the method to provide value equality, and a `Point3D` class that is derived from `Point`. Because `Point` overrides to test for value equality, the method is not called. However, `Point3D.Equals` calls `Point.Equals` because `Point` implements in a manner that provides value equality. + +:::code language="csharp" source="~/snippets/csharp/System/Object/Equals/equals2.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/Equals/equals2.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/Equals/equals2.vb" id="Snippet1"::: + +The `Point.Equals` method checks to make sure that the `obj` argument is not **null** and that it references an instance of the same type as this object. If either check fails, the method returns `false`. + +The `Point.Equals` method calls the method to determine whether the runtime types of the two objects are identical. If the method used a check of the form `obj is Point` in C# or `TryCast(obj, Point)` in Visual Basic, the check would return `true` in cases where `obj` is an instance of a derived class of `Point`, even though `obj` and the current instance are not of the same runtime type. Having verified that both objects are of the same type, the method casts `obj` to type `Point` and returns the result of comparing the instance fields of the two objects. + +In `Point3D.Equals`, the inherited `Point.Equals` method, which overrides , is invoked before anything else is done. Because `Point3D` is a sealed class (`NotInheritable` in Visual Basic), a check in the form `obj is Point` in C# or `TryCast(obj, Point)` in Visual Basic is adequate to ensure that `obj` is a `Point3D` object. If it is a `Point3D` object, it is cast to a `Point` object and passed to the base class implementation of . Only when the inherited `Point.Equals` method returns `true` does the method compare the `z` instance fields introduced in the derived class. + +The following example defines a `Rectangle` class that internally implements a rectangle as two `Point` objects. The `Rectangle` class also overrides to provide for value equality. + +:::code language="csharp" source="~/snippets/csharp/System/Object/Equals/equals3.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/Equals/equals3.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/Equals/equals3.vb" id="Snippet1"::: + +Some languages such as C# and Visual Basic support operator overloading. When a type overloads the equality operator, it must also override the method to provide the same functionality. This is typically accomplished by writing the method in terms of the overloaded equality operator, as in the following example. + +:::code language="csharp" source="~/snippets/csharp/System/Object/Equals/equals4.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/Equals/equals4.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/Equals/equals4.vb" id="Snippet1"::: + +Because `Complex` is a value type, it cannot be derived from. Therefore, the override to method need not call to determine the precise runtime type of each object, but can instead use the `is` operator in C# or the `TypeOf` operator in Visual Basic to check the type of the `obj` parameter. + + ]]> + @@ -289,7 +460,77 @@ The following example defines a Point type derived from the Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. - For more information about this API, see Supplemental API remarks for Object.Finalize. + + method is used to perform cleanup operations on unmanaged resources held by the current object before the object is destroyed. The method is protected and therefore is accessible only through this class or through a derived class. + +## How finalization works + +The class provides no implementation for the method, and the garbage collector does not mark types derived from for finalization unless they override the method. + +If a type does override the method, the garbage collector adds an entry for each instance of the type to an internal structure called the finalization queue. The finalization queue contains entries for all the objects in the managed heap whose finalization code must run before the garbage collector can reclaim their memory. The garbage collector then calls the method automatically when it discovers that an object is inaccessible, unless the object has been exempted from finalization by a call to the method. + + is automatically called only once on a given instance, unless the object is re-registered by using a mechanism such as and the method has not been subsequently called. + + operations have the following limitations: + +- The exact time when the finalizer executes is undefined. To ensure deterministic release of resources for instances of your class, implement a `Close` method or provide a implementation. +- The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already been finalized when the finalizer of Object A starts. +- The thread on which the finalizer runs is unspecified. + +The method might not run to completion or might not run at all under the following exceptional circumstances: + +- If another finalizer blocks indefinitely (goes into an infinite loop, tries to obtain a lock it can never obtain, and so on). Because the runtime tries to run finalizers to completion, other finalizers might not be called if a finalizer blocks indefinitely. +- If the process terminates without giving the runtime a chance to clean up. In this case, the runtime's first notification of process termination is a DLL_PROCESS_DETACH notification. + +The runtime continues to finalize objects during shutdown only while the number of finalizable objects continues to decrease. + +If or an override of throws an exception, and the runtime is not hosted by an application that overrides the default policy, the runtime terminates the process and no active `try`/`finally` blocks or finalizers are executed. This behavior ensures process integrity if the finalizer cannot free or destroy resources. + +## Overriding the Finalize method + +You should override for a class that uses unmanaged resources, such as file handles or database connections that must be released when the managed object that uses them is discarded during garbage collection. You shouldn't implement a method for managed objects because the garbage collector releases managed resources automatically. + +> [!IMPORTANT] +> If a object is available that wraps your unmanaged resource, the recommended alternative is to implement the dispose pattern with a safe handle and not override . For more information, see [The SafeHandle alternative](#the-safehandle-alternative) section. + +The method does nothing by default, but you should override only if necessary, and only to release unmanaged resources. Reclaiming memory tends to take much longer if a finalization operation runs, because it requires at least two garbage collections. In addition, you should override the method for reference types only. The common language runtime only finalizes reference types. It ignores finalizers on value types. + +The scope of the method is `protected`. You should maintain this limited scope when you override the method in your class. By keeping a method protected, you prevent users of your application from calling an object's method directly. + +Every implementation of in a derived type must call its base type's implementation of . This is the only case in which application code is allowed to call . An object's method shouldn't call a method on any objects other than that of its base class. This is because the other objects being called could be collected at the same time as the calling object, such as in the case of a common language runtime shutdown. + +> [!NOTE] +> The C# compiler does not allow you to override the method. Instead, you provide a finalizer by implementing a [destructor](/dotnet/csharp/programming-guide/classes-and-structs/destructors) for your class. A C# destructor automatically calls the destructor of its base class. +> +> Visual C++ also provides its own syntax for implementing the method. For more information, see the "Destructors and finalizers" section of [How to: Define and Consume Classes and Structs (C++/CLI)](/cpp/dotnet/how-to-define-and-consume-classes-and-structs-cpp-cli). + +Because garbage collection is non-deterministic, you do not know precisely when the garbage collector performs finalization. To release resources immediately, you can also choose to implement the [dispose pattern](/dotnet/standard/garbage-collection/implementing-dispose) +and the interface. The implementation can be called by consumers of your class to free unmanaged resources, and you can use the method to free unmanaged resources in the event that the method is not called. + + can take almost any action, including resurrecting an object (that is, making the object accessible again) after it has been cleaned up during garbage collection. However, the object can only be resurrected once; cannot be called on resurrected objects during garbage collection. + +## The SafeHandle alternative + +Creating reliable finalizers is often difficult, because you cannot make assumptions about the state of your application, and because unhandled system exceptions such as and terminate the finalizer. Instead of implementing a finalizer for your class to release unmanaged resources, you can use an object that is derived from the class to wrap your unmanaged resources, and then implement the dispose pattern without a finalizer. .NET provides the following classes in the namespace that are derived from : + +- is a wrapper class for a file handle. +- is a wrapper class for memory-mapped file handles. +- is a wrapper class for a pointer to a block of unmanaged memory. +- , , and are wrapper classes for cryptographic handles. +- is a wrapper class for pipe handles. +- is a wrapper class for a handle to a registry key. +- is a wrapper class for a wait handle. + +The following example uses the [dispose pattern](/dotnet/standard/garbage-collection/implementing-dispose) with safe handles instead of overriding the method. It defines a `FileAssociation` class that wraps registry information about the application that handles files with a particular file extension. The two registry handles returned as `out` parameters by Windows [RegOpenKeyEx](/windows/win32/api/winreg/nf-winreg-regopenkeyexa) function calls are passed to the constructor. The type's protected `Dispose` method then calls the `SafeRegistryHandle.Dispose` method to free these two handles. + +:::code language="csharp" source="~/snippets/csharp/System/Object/Finalize/finalize_safe.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/Finalize/finalize_safe.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/Finalize/finalize_safe.vb" id="Snippet2"::: + + ]]> + method is called when an object that overrides is destroyed. Note that, in a production application, the method would be overridden to release unmanaged resources held by the object. Also note that the C# example provides a destructor instead of overriding the method. @@ -348,7 +589,57 @@ For an additional example that overrides the meth Serves as the default hash function. A hash code for the current object. - For more information about this API, see Supplemental API remarks for Object.GetHashCode. + + method provides a hash code for algorithms that need quick checks of object equality. A hash code is a numeric value that is used to insert and identify an object in a hash-based collection, such as the class, the class, or a type derived from the class. + +> [!NOTE] +> For information about how hash codes are used in hash tables and for some additional hash code algorithms, see the [Hash Function](https://en.wikipedia.org/wiki/Hash_function) entry in Wikipedia. + +Two objects that are equal return hash codes that are equal. However, the reverse is not true: equal hash codes do not imply object equality, because different (unequal) objects can have identical hash codes. Furthermore, .NET does not guarantee the default implementation of the method, and the value this method returns might differ between .NET implementations and platforms, such as between 32-bit and 64-bit platforms. For these reasons, do not use the default implementation of this method as a unique object identifier for hashing purposes. Two consequences follow from this: + +- You should not assume that equal hash codes imply object equality. +- You should never persist or use a hash code outside the application domain in which it was created, because the same object may hash across application domains, processes, and platforms. + +> [!WARNING] +> A hash code is intended for efficient insertion and lookup in collections that are based on a hash table. A hash code is not a permanent value. For this reason: +> +> - Do not serialize hash code values or store them in databases. +> - Do not use the hash code as the key to retrieve an object from a keyed collection. +> - Do not send hash codes across application domains or processes. In some cases, hash codes may be computed on a per-process or per-application domain basis. +> - Do not use the hash code instead of a value returned by a cryptographic hashing function if you need a cryptographically strong hash. For cryptographic hashes, use a class derived from the or class. +> - Do not test for equality of hash codes to determine whether two objects are equal. (Unequal objects can have identical hash codes.) To test for equality, call the or method. + +The method can be overridden by a derived type. If is not overridden, hash codes for reference types are computed by calling the method of the base class, which computes a hash code based on an object's reference; for more information, see . In other words, two objects for which the method returns `true` have identical hash codes. If value types do not override , the method of the base class uses reflection to compute the hash code based on the values of the type's fields. In other words, value types whose fields have equal values have equal hash codes. For more information about overriding , see the "Notes to Inheritors" section. + +> [!WARNING] +> If you override the method, you should also override , and vice versa. If your overridden method returns `true` when two objects are tested for equality, your overridden method must return the same value for the two objects. + +If an object that is used as a key in a hash table does not provide a useful implementation of , you can specify a hash code provider by supplying an implementation to one of the overloads of the class constructor. + +## Examples + +One of the simplest ways to compute a hash code for a numeric value that has the same or a smaller range than the type is to simply return that value. The following example shows such an implementation for a `Number` structure. + +:::code language="csharp" source="~/snippets/csharp/System/Object/GetHashCode/direct1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/GetHashCode/direct1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/GetHashCode/direct1.vb" id="Snippet1"::: + +Frequently, a type has multiple data fields that can participate in generating the hash code. One way to generate a hash code is to combine these fields using an `XOR (eXclusive OR)` operation, as shown in the following example. + +:::code language="csharp" source="~/snippets/csharp/System/Object/GetHashCode/xor1.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/GetHashCode/xor1.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/GetHashCode/xor1.vb" id="Snippet2"::: + +The previous example returns the same hash code for (n1, n2) and (n2, n1), and so it might generate more collisions than are desirable. On .NET 5+, the recommended solution is to use . It avoids the symmetry problem and produces a well-distributed hash code without the overhead of creating a `Tuple` object. + +:::code language="csharp" source="~/snippets/csharp/System/Object/GetHashCode/xor2.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/GetHashCode/xor2.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/GetHashCode/xor2.vb" id="Snippet3"::: + + ]]> + A hash function is used to quickly generate a number (hash code) that corresponds to the value of an object. Hash functions are usually specific to each type and, for uniqueness, must use at least one of the instance fields as input. Hash codes should not be computed by using the values of static fields. @@ -676,7 +967,153 @@ To illustrate the difference between a shallow and a deep copy operation, consid Returns a string that represents the current object. A string that represents the current object. - For more information about this API, see Supplemental API remarks for Object.ToString. + + is a common formatting method in .NET. It converts an object to its string representation so that it is suitable for display. (For information about formatting support in .NET, see [Formatting Types](/dotnet/standard/base-types/formatting-types).) Default implementations of the method return the fully qualified name of the object's type. + +> [!IMPORTANT] +> You may have reached this page by following the link from the member list of another type. That is because that type does not override . Instead, it inherits the functionality of the method. + +Types frequently override the method to provide a more suitable string representation of a particular type. Types also frequently overload the method to provide support for format strings or culture-sensitive formatting. + +## The default Object.ToString() method + +The default implementation of the method returns the fully qualified name of the type of the , as the following example shows. + +:::code language="csharp" source="~/snippets/csharp/System/Object/ToString/tostring1.cs" id="Snippet1"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/ToString/tostring1.fs" id="Snippet1"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/ToString/tostring1.vb" id="Snippet1"::: + +Because is the base class of all reference types in .NET, this behavior is inherited by reference types that do not override the method. The following example illustrates this. It defines a class named `Object1` that accepts the default implementation of all members. Its method returns the object's fully qualified type name. + +:::code language="csharp" source="~/snippets/csharp/System/Object/ToString/tostring2.cs" id="Snippet2"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/ToString/tostring2.fs" id="Snippet2"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/ToString/tostring2.vb" id="Snippet2"::: + +## Override the Object.ToString() method + +Types commonly override the method to return a string that represents the object instance. For example, the base types such as , , and provide implementations that return the string form of the value that the object represents. The following example defines a class, `Object2`, that overrides the method to return the type name along with its value. + +:::code language="csharp" source="~/snippets/csharp/System/Object/ToString/tostring3.cs" id="Snippet3"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/ToString/tostring3.fs" id="Snippet3"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/ToString/tostring3.vb" id="Snippet3"::: + +The following table lists the type categories in .NET and indicates whether or not they override the method. + +| Type category | Overrides Object.ToString() | Behavior | +|---------------|-----------------------------|----------| +| Class | n/a | n/a | +| Structure | Yes () | Same as `Object.ToString()` | +| Enumeration | Yes () | The member name | +| Interface | No| n/a | +| Delegate | No| n/a | + +See the Notes to Inheritors section for additional information on overriding . + +## Overload the ToString method + +In addition to overriding the parameterless method, many types overload the `ToString` method to provide versions of the method that accept parameters. Most commonly, this is done to provide support for variable formatting and culture-sensitive formatting. + +The following example overloads the `ToString` method to return a result string that includes the value of various fields of an `Automobile` class. It defines four format strings: G, which returns the model name and year; D, which returns the model name, year, and number of doors; C, which returns the model name, year, and number of cylinders; and A, which returns a string with all four field values. + +:::code language="csharp" source="~/snippets/csharp/System/Object/ToString/tostringoverload1.cs" id="Snippet4"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/ToString/tostringoverload1.fs" id="Snippet4"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/ToString/tostringoverload1.vb" id="Snippet4"::: + +The following example calls the overloaded method to display culture-sensitive formatting of a currency value. + +:::code language="csharp" source="~/snippets/csharp/System/Object/ToString/tostringoverload2.cs" id="Snippet5"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/ToString/tostringoverload2.fs" id="Snippet5"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/ToString/tostringoverload2.vb" id="Snippet5"::: + +For more information on format strings and culture-sensitive formatting, see [Formatting Types](/dotnet/standard/base-types/formatting-types). For the format strings supported by numeric 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). For the format strings supported by date and time 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). + +## Extend the Object.ToString method + +Because a type inherits the default method, you may find its behavior undesirable and want to change it. This is particularly true of arrays and collection classes. While you may expect the `ToString` method of an array or collection class to display the values of its members, it instead displays the type fully qualified type name, as the following example shows. + +:::code language="csharp" source="~/snippets/csharp/System/Object/ToString/array1.cs" id="Snippet6"::: +:::code language="fsharp" source="~/snippets/fsharp/System/Object/ToString/array1.fs" id="Snippet6"::: +:::code language="vb" source="~/snippets/visualbasic/System/Object/ToString/array1.vb" id="Snippet6"::: + +You have several options to produce the result string that you'd like. + +- If the type is an array, a collection object, or an object that implements the or interfaces, you can enumerate its elements by using the `foreach` statement in C# or the `For Each...Next` construct in Visual Basic. + +- If the class is not `sealed` (in C#) or `NotInheritable` (in Visual Basic), you can develop a wrapper class that inherits from the base class whose method you want to customize. At a minimum, this requires that you do the following: + + 1. Implement any necessary constructors. Derived classes do not inherit their base class constructors. + 2. Override the method to return the result string that you'd like. + + The following example defines a wrapper class for the class. It overrides the method to display the value of each method of the collection rather than the fully qualified type name. + + :::code language="csharp" source="~/snippets/csharp/System/Object/ToString/customize1.cs" id="Snippet7"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Object/ToString/customize1.fs" id="Snippet7"::: + :::code language="vb" source="~/snippets/visualbasic/System/Object/ToString/customize1.vb" id="Snippet7"::: + +- Develop an [extension method](/dotnet/standard/design-guidelines/extension-methods) that returns the result string that you want. Note that you can't override the default method in this way—that is, your extension class (in C#) or module (in Visual Basic) cannot have a parameterless method named `ToString` that's called in place of the original type's `ToString` method. You'll have to provide some other name for your parameterless `ToString` replacement. + + The following example defines two methods that extend the class: a parameterless `ToString2` method, and a `ToString` method with a parameter that represents a format string. + + :::code language="csharp" source="~/snippets/csharp/System/Object/ToString/customize2.cs" id="Snippet8"::: + :::code language="fsharp" source="~/snippets/fsharp/System/Object/ToString/customize2.fs" id="Snippet8"::: + :::code language="vb" source="~/snippets/visualbasic/System/Object/ToString/customize2.vb" id="Snippet8"::: + +## Notes for the Windows Runtime + +When you call the method on a class in the Windows Runtime, it provides the default behavior for classes that don't override . This is part of the support that .NET provides for the Windows Runtime (see [.NET Support for Windows Store Apps and Windows Runtime](/dotnet/standard/cross-platform/support-for-windows-store-apps-and-windows-runtime)). Classes in the Windows Runtime don't inherit , and don't always implement a . However, they always appear to have , , and methods when you use them in your C# or Visual Basic code, and .NET provides a default behavior for these methods. + +The common language runtime uses [IStringable.ToString](xref:Windows.Foundation.IStringable.ToString) on a Windows Runtime object before falling back to the default implementation of . + +> [!NOTE] +> Windows Runtime classes that are written in C# or Visual Basic can override the method. + +### The Windows Runtime and the IStringable Interface + +The Windows Runtime includes an [IStringable](xref:Windows.Foundation.IStringable) interface whose single method, [IStringable.ToString](xref:Windows.Foundation.IStringable.ToString), provides basic formatting support comparable to that provided by . To prevent ambiguity, you should not implement [IStringable](xref:Windows.Foundation.IStringable) on managed types. + +When managed objects are called by native code or by code written in languages such as JavaScript or C++/CX, they appear to implement [IStringable](xref:Windows.Foundation.IStringable). The common language runtime automatically routes calls from [IStringable.ToString](xref:Windows.Foundation.IStringable.ToString) to if [IStringable](xref:Windows.Foundation.IStringable) is not implemented on the managed object. + +> [!WARNING] +> Because the common language runtime auto-implements [IStringable](xref:Windows.Foundation.IStringable) for all managed types in Windows Store apps, we recommend that you do not provide your own `IStringable` implementation. Implementing `IStringable` may result in unintended behavior when calling `ToString` from the Windows Runtime, C++/CX, or JavaScript. + +If you do choose to implement [IStringable](xref:Windows.Foundation.IStringable) in a public managed type that's exported in a Windows Runtime component, the following restrictions apply: + +- You can define the [IStringable](xref:Windows.Foundation.IStringable) interface only in a "class implements" relationship, as follows: + + ```csharp + public class NewClass : IStringable + ``` + + ```vb + Public Class NewClass : Implements IStringable + ``` + +- You cannot implement [IStringable](xref:Windows.Foundation.IStringable) on an interface. + +- You cannot declare a parameter to be of type [IStringable](xref:Windows.Foundation.IStringable). + +- [IStringable](xref:Windows.Foundation.IStringable) cannot be the return type of a method, property, or field. + +- You cannot hide your [IStringable](xref:Windows.Foundation.IStringable) implementation from base classes by using a method definition such as the following: + + ```csharp + public class NewClass : IStringable + { + public new string ToString() + { + return "New ToString in NewClass"; + } + } + ``` + + Instead, the [IStringable.ToString](xref:Windows.Foundation.IStringable.ToString) implementation must always override the base class implementation. You can hide a `ToString` implementation only by invoking it on a strongly typed class instance. + +Under a variety of conditions, calls from native code to a managed type that implements [IStringable](xref:Windows.Foundation.IStringable) or hides its [ToString](xref:Windows.Foundation.IStringable.ToString) implementation can produce unexpected behavior. + + ]]> + When you implement your own types, you should override the method to return values that are meaningful for those types. Derived classes that require more control over formatting than provides can implement the interface. Its method enables you to define format strings that control formatting and to use an object that can provide for culture-specific formatting.