# C# Study - Questions 1 ###### tags: `C#` `Study` `Questions` --- # [Final variables in C#](https://www.tutorialspoint.com/Final-variables-in-Chash) Java has a ``final`` keyword, but __C# does not have its implementation. Use the ``sealed`` or ``readonly`` keyword in C# __for the same implementation__. The ``readonly`` would allow the variables to be assigned a value only once. A field marked "read-only", can only be set once __during the construction of an object__. It cannot be changed. 當 object 在 construction 過程中,其 readonly variables 只允許被 assign 一次 Example: ``` class Employee { readonly int age; Employee(int age) { this.age = age; } void ChangeAge() { //age = 27; // Compile error } } ``` Above, we have set the ``age`` field as ``readonly``, which once assigned cannot be changed. (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/readonly) (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed) (https://www.c-sharpcorner.com/article/sealed-class-in-C-Sharp/) --- Main() and command-line arguments (C# Programming Guide) 08/02/2017 The ``Main`` method is the __entry point of a C# application__. (__Libraries and services do not require a ``Main`` method as an entry point.__) When the application is started, the Main method is the first method that is invoked. There can only be one entry point in a C# program. If you have more than one class that has a Main method, you must compile your program with the -main compiler option to specify which Main method to use as the entry point. For more information, see -main --- [C# Main Method](https://www.completecsharptutorial.com/basic/main-method.php) In C# programming the Main method is where program starts execution. It is the main entry point of program that executes all the objects and invokes method to execute. __There can be only one Main method in C#__. However, the C# Main method can be ``void`` or ``int`` return type. __It must be inside a ``class`` or ``struct`` and must be declared with ``static`` modifier__. It is the main place where a program starts the execution and end. The Main method can have a parameter and these parameters are known as zero-indexed command line argument. In lateral chapter you will learn more about command line argument. --- # [Difference between namespace in C# and packages in Java](https://www.tutorialspoint.com/difference-between-namespace-in-chash-and-packages-in-java) ## Packages in Java Packages are used in Java in order to * prevent naming conflicts, * to control access, * to make searching/locating and usage of classes, interfaces, enumerations and annotations easier, etc. 避免名稱相衝 控制 access 找尋 class, interface 等更快 在 Java, 檔案的目錄結構要與 package name 相同 A namespace is designed for providing a way to keep one set of names separate from another. The class names declared in one namespace does not conflict with the same class names declared in another. Define a Package as − ``` package package_name; ``` Restrict the access of classes (or class members) to the classes within the same package, but in C# with namespaces you cannot achieve this. package 能限制相同 package 中 class 彼此之間的 access 但 C#, class 在相同 namespaces 無法限制 access --> 這要如何驗證? ## Namespace in C# A namespace is designed for providing a way to keep one set of names separate from another. The class names declared in one namespace does not conflict with the same class names declared in another. Define a Namespace as − ``` namespace namespace_name { // code declarations } ``` In Java, the __directory structure should match the package structure__, but not required in C#. In C#, add multiple namespaces in one file, whereas in Java, a file belongs to a package. --- #[What is the Difference Between Namespace and Package](https://pediaa.com/what-is-the-difference-between-namespace-and-package/#:~:text=The%20main%20difference%20between%20namespace,interfaces%20to%20improve%20code%20maintainability.) The main difference between namespace and package is that namespace is available in C# (.NET) to __organize the classes__ so that it is easier to handle the application, while package is available in Java and __groups similar type of classes and interfaces to improve code maintainability__. Generally, a computer program is a set of instructions that instruct the CPU to perform a specific task. A programmer can write a program using a programming language. One such programing language type is a high-level programming language. It is easier for a programmer to read and understand the syntax of high-level programming languages. Two such programming languages are Java and C#. Of these, Java has a concept called packages while C# has a concept called namespace. ## What is Namespace Namespace in C# helps to organize classes. Therefore, namespaces help to manage the application. In a simple C# program, the programmer uses the statement ``System.Console``. It describes that __the namespace is ``System`` and the class is ``Console``__. Besides, __to access the class of a namespace__, the programmer should write this syntax, ``namespace_name.classname``. However, the programmer can avoid writing the entire name each time by ``using`` keyword. Difference Between Namespace and Package Figure 1: C# program with namespace In the above program, the namespace is ``ConsoleApplication1``. It has a class and the main program is inside that class. Therefore, it will print the message on the console. Here, the __``using`` statement__ is used instead of writing the complete name to access a namespace. Furthermore, global namespace is a root namespace. Moreover, ``global::System`` will always refer to the ``System`` namespace in the .NET framework. ## Difference Between Namespace and Package ### Definition A namespace is a __logical division__ of classes in the .NET framework, while the package is __an organized set of related classes and interfaces__. Hence, this explains the main Namespace is a logical division of classes in the .NET framework, while the package is an organized set of related classes and interfaces. ### Usage Furthermore, the namespace is used to organize programs, both as an “internal” organization system for a program and as an “external” organization system. But, the package is used to __organize files or public types to avoid type conflicts__. Thus, this is another difference between namespace and package. ## Conclusion Namespace and package are two concepts available in programming. The main difference between namespace and package is that namespace is available in C# to organize the classes so that it is easier to handle the application while package, which is available in Java, group similar type of classes and interfaces to improve code maintainability. In brief, they both are similar but they belong to different languages. --- [Check if instance is of a type](https://stackoverflow.com/questions/3561202/check-if-instance-is-of-a-type) The different answers here have two different meanings. If you want to check whether an instance is of an exact type then ``` if (c.GetType() == typeof(TForm)) ``` is the way to go. If you want to know whether c is an instance of TForm or a subclass then use is/as: ``` if (c is TForm) //or TForm form = c as TForm; if (form != null) ``` It's worth being clear in your mind about which of these behaviour you actually want. --- # Difference between virtual and abstract methods ## [Object.ToString Method](https://docs.microsoft.com/en-us/dotnet/api/system.object.tostring?view=net-5.0) Namespace: System Returns a string that represents the current object. ``` public virtual string ToString (); ``` ## [What is the difference between an abstract function and a virtual function?](https://stackoverflow.com/questions/391483/what-is-the-difference-between-an-abstract-function-and-a-virtual-function) An ``abstract`` function __cannot have functionality__. You're basically saying, __any child class MUST give their own version of this method__, however it's too general to even try to implement in the parent class. A ``virtual`` function, is basically saying look, __here's the functionality that may or may not be good enough for the child class. So if it is good enough, use this method, if not, then ``override`` me, and provide your own functionality. ## [Difference between virtual and abstract methods [duplicate](https://stackoverflow.com/questions/14728761/difference-between-virtual-and-abstract-methods) Virtual methods have an implementation and provide the derived classes with the option of overriding it. Abstract methods do not provide an implementation and force the derived classes to override the method. So, abstract methods have no actual code in them, and subclasses HAVE TO override the method. Virtual methods can have code, which is usually a default implementation of something, and any subclasses CAN override the method using the override modifier and provide a custom implementation. ``` public abstract class E { public abstract void AbstractMethod(int i); public virtual void VirtualMethod(int i) { // Default implementation which can be overridden by subclasses. } } public class D : E { public override void AbstractMethod(int i) { // You HAVE to override this method } public override void VirtualMethod(int i) { // You are allowed to override this method. } } ``` --- ## Forbid method override 假設我有 * ``interface IPdfExtractorService``, * ``abstract class AbsPdfExtractorService`` 和 * ``MyPdfExtractorService1`` 想要 ``AbsPdfExtractorService`` 實作以下兩個 methods * ``Task<FmApiResult<string>> ExtractTextFromPdfWithCatchAsync(string filePath);`` * ``FmApiResult<string> ExtractWithPdfPigWithCatch(string filePath);`` 留下 * ``Task<FmApiResult<string>> ExtractWithOcrWithCatchAsync(string filePath);`` 給 Sub-class ``MyPdfExtractorService1`` 實作。 如``AbsPdfExtractorService`` 中 的 method 若沒加上 keyword ``virtual`` 或 ``abstract``, Sub-class ``MyPdfExtractorService1`` 是無法進行 override 並實作內容的! ``` public interface IPdfExtractorService { Task<FmApiResult<string>> ExtractTextFromPdfWithCatchAsync(string filePath); FmApiResult<string> ExtractWithPdfPigWithCatch(string filePath); Task<FmApiResult<string>> ExtractWithOcrWithCatchAsync(string filePath); } public abstract class AbsPdfExtractorService : IPdfExtractorService { protected readonly IOcrService _ocrService; public AbsPdfExtractorService(IOcrService ocrService) { _ocrService = ocrService; } public async Task<FmApiResult<string>> ExtractTextFromPdfWithCatchAsync(string filePath) { // First try with PdfPig FmApiResult<string> directResult = ExtractWithPdfPigWithCatch(filePath); switch (directResult) { case FmApiResult<string>.Success success: Debug.WriteLine($"PdfExtractorService.ExtractTextFromPdfWithCatchAsync() - ExtractWithPdfPigWithCatch() returns OK"); if (string.IsNullOrWhiteSpace(success.Data)) { return await ExtractWithOcrWithCatchAsync(filePath); } else { return new FmApiResult<string>.Success(success.Data); } case FmApiResult<string>.Error error: return await ExtractWithOcrWithCatchAsync(filePath); default: return new FmApiResult<string>.Error( new FmRuntimeException(BaseErrorCodes.UNKNOWN_ERROR, "PdfExtractorService.ExtractTextFromPdfWithCatchAsync()") ); } } public FmApiResult<string> ExtractWithPdfPigWithCatch(string filePath) { Debug.WriteLine($"PdfExtractorService.ExtractWithPdfPigWithCatch() - for path [{filePath}]"); try { StringBuilder text = new StringBuilder(); using (UglyToad.PdfPig.PdfDocument document = UglyToad.PdfPig.PdfDocument.Open(filePath)) { foreach (UglyToad.PdfPig.Content.Page page in document.GetPages()) { text.AppendLine(page.Text); } } return new FmApiResult<string>.Success(text.ToString()); } catch (Exception cause) { return new FmApiResult<string>.Error( new FmRuntimeException(BaseErrorCodes.INTERNAL_CONVERSION_ERROR, $"PDF direct extraction failed: {cause.Message}", cause)); } } public abstract Task<FmApiResult<string>> ExtractWithOcrWithCatchAsync(string filePath); } public sealed class MyPdfExtractorService1 : AbsPdfExtractorService { public MyPdfExtractorService1(IOcrService ocrService) : base(ocrService) { } // to allow override, the parent's the same method need to add "virtual" keyword!! //public override async Task<FmApiResult<string>> ExtractTextFromPdfWithCatchAsync(string filePath) //{ // return await Task.Run(() => // { // return new FmApiResult<string>.Success(""); // }); //} // ONLY this method can be implemented public override async Task<FmApiResult<string>> ExtractWithOcrWithCatchAsync(string filePath) { Debug.WriteLine($"PdfExtractorService.ExtractWithOcrWithCatchAsync() - for path [{filePath}]"); try { StringBuilder accumulatedText = new StringBuilder(); using (PdfiumViewer.PdfDocument pdfDocument = PdfiumViewer.PdfDocument.Load(filePath)) { for (int i = 0; i < pdfDocument.PageCount; i++) { using System.Drawing.Image pdfPageImage = pdfDocument.Render(i, 300, 300, true); FmApiResult<string> textResult = await _ocrService.ExtractTextFromImageWithCatchAsync(pdfPageImage); switch (textResult) { case FmApiResult<string>.Success success: Debug.WriteLine($"PdfExtractorService.ExtractWithOcrWithCatchAsync - OcrService.ExtractTextFromImageWithCatchAsync() - OK for Page [{i}]"); accumulatedText.Append(success.Data).AppendLine(); break; case FmApiResult<string>.Error error: Debug.WriteLine($"Error on PdfExtractorService.ExtractWithOcrWithCatchAsync - OcrService.ExtractTextFromImageWithCatchAsync - Page [{i}], Error:", error.Cause); break; } } } return new FmApiResult<string>.Success(accumulatedText.ToString()); } catch (Exception cause) { Debug.WriteLine($"Error on PdfExtractorService.ExtractWithOcrWithCatch()", cause); return new FmApiResult<string>.Error( new FmRuntimeException(BaseErrorCodes.INTERNAL_CONVERSION_ERROR, $"PDF OCR fallback failed: {cause.Message}", cause)); } } } ``` --- # List ## .NET ``System.Collections.Generic.List`` ``` void ArrayLists() { List<int> myList = new List<int>(); myList.Add(1); myList.Insert(1, 2); int i = 1; myList[0] = i; i = myList[0]; } ``` ## [Something similar to C# .NET Generic List in java](https://stackoverflow.com/questions/10115769/something-similar-to-c-sharp-net-generic-list-in-java) ### Accessing a Generic List You can get and insert the elements of a generic List like this: ``` List<String> list = new ArrayList<String>(); String string1 = "a string"; list.add(string1); String string2 = list.get(0); ``` Notice how it is not necessary to cast the object obtained from the List.get() method call, as is normally necessary. The compiler knows that this List can only contain String instances, so casts are not necessary. ### Iterating a Generic List You can iterate a generic List using an iterator, like this: ``` List<String> list = new ArrayList<String>(); Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String aString = iterator.next(); } ``` Notice how it is not necessary to cast the object returned from the iterator.next() next call. Because the List is generified (has a type), the compiler knows that it contains String instances. Therefore it is not necessary to cast the objects obtained from it, even if it comes from its Iterator. You can also use the new for-loop, like this: ``` List<String> list = new ArrayList<String>(); for(String aString : list) { System.out.println(aString); } ``` Notice how a String variable is declared inside the parantheses of the for-loop. For each iteration (each element in the List) this variable contains the current element (current String). --- # User defined Exception ## [Custom Exception Type in C#](https://www.tutorialsteacher.com/csharp/custom-exception-csharp) C# includes the built-in exception types such as ``NullReferenceException``, ``MemoryOverflowException``, etc. However, you often like to raise an exception when the business rule of your application gets violated. So, for this, you can create a custom exception class by deriving the ``ApplicationException`` class. The .Net framework includes ``ApplicationException`` class since .Net v1.0. It was designed to use as a base class for the custom exception class. However, __Microsoft now recommends ``Exception`` class to create a custom exception class__. For example, create ``InvalidStudentNameException`` class in a school application, which does not allow any special character or numeric value in a name of any of the students. ``` class Student { public int StudentID { get; set; } public string StudentName { get; set; } } [Serializable] class InvalidStudentNameException : Exception { public InvalidStudentNameException() { } public InvalidStudentNameException(string name) : base(String.Format("Invalid Student Name: {0}", name)) { } } ``` Now, you can raise ``InvalidStudentNameException`` in your program whenever the name contains special characters or numbers. Use the ``throw`` keyword to raise an exception. ``` class Program { static void Main(string[] args) { Student newStudent = null; try { newStudent = new Student(); newStudent.StudentName = "James007"; ValidateStudent(newStudent); } catch(InvalidStudentNameException ex) { Console.WriteLine(ex.Message ); } Console.ReadKey(); } private static void ValidateStudent(Student std) { Regex regex = new Regex("^[a-zA-Z]+$"); if (!regex.IsMatch(std.StudentName)) { throw new InvalidStudentNameException(std.StudentName); } } } ``` --- ## [How to create user-defined exceptions](https://docs.microsoft.com/en-us/dotnet/standard/exceptions/how-to-create-user-defined-exceptions) ``` using System; public class EmployeeListNotFoundException : Exception { public EmployeeListNotFoundException() {} public EmployeeListNotFoundException(string message): base(message) { } public EmployeeListNotFoundException(string message, Exception inner): base(message, inner) { } } ``` --- ## [Custom Exception in C#](https://dotnettutorials.net/lesson/create-custom-exception-csharp/) ``` namespace ExceptionHandlingDemo { //Creating our own Exception Class by inheriting Exception class public class OddNumberException : Exception { //Overriding the Message property public override string Message { get { return "divisor cannot be odd number"; } } } class Program { static void Main(string[] args) { int x, y, z; Console.WriteLine("ENTER TWO INTEGER NUMBERS:"); x = int.Parse(Console.ReadLine()); y = int.Parse(Console.ReadLine()); try { if (y % 2 > 0) { //OddNumberException ONE = new OddNumberException(); //throw ONE; throw new OddNumberException(); } z = x / y; Console.WriteLine(z); } catch (OddNumberException one) { Console.WriteLine(one.Message); } Console.WriteLine("End of the program"); Console.ReadKey(); } } } ``` --- # Explicit Interface Implementation ## [Explicit Interface Implementation (C# Programming Guide)](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation) If a class implements two interfaces that contain __a member with the same signature__, then implementing that member on the class will cause both interfaces to use that member as their implementation. In the following example, all the calls to Paint invoke the same method. This first sample defines the types: ``` public interface IControl { void Paint(); } public interface ISurface { void Paint(); } public class SampleClass : IControl, ISurface { // Both ISurface.Paint and IControl.Paint call this method. public void Paint() { Console.WriteLine("Paint method in SampleClass"); } } ``` When two interface members don't perform the same function, it leads to an incorrect implementation of one or both of the interfaces. It's possible to implement an interface member __explicitly—creating a class member that is only called through the interface, and is specific to that interface__. Name the class member with the name of the interface and a period. For example: ``` public class SampleClass : IControl, ISurface { void IControl.Paint() { // Explicit implementation System.Console.WriteLine("IControl.Paint"); } void ISurface.Paint() { // Explicit implementation System.Console.WriteLine("ISurface.Paint"); } } ``` The class member ``IControl.Paint`` is only available through the ``IControl`` interface, and ``ISurface.Paint`` is only available through ``ISurface``. __Both method implementations are separate__, and neither are available directly on the class. For example: ``` // Call the Paint methods from Main. SampleClass obj = new SampleClass(); //obj.Paint(); // Compiler error. IControl c = obj; c.Paint(); // Calls IControl.Paint on SampleClass. ISurface s = obj; s.Paint(); // Calls ISurface.Paint on SampleClass. // Output: // IControl.Paint // ISurface.Paint ``` __Explicit implementation__ is also used to __resolve cases where two interfaces each declare different members of the same name such as a property and a method. To implement both interfaces, a class has to use explicit implementation either for the property P, or the method P, or both, to avoid a compiler error. For example: ``` interface ILeft { int P { get;} } interface IRight{ int P(); } class Middle : ILeft, IRight { public int P() { return 0; } int ILeft.P { get { return 0; } } // Explicit implementation } ``` Beginning with C# 8.0, you can define an implementation for members declared in an interface. If a class inherits a method implementation from an interface, that method is only accessible through a reference of the interface type. The inherited member doesn't appear as part of the public interface. The following sample defines a __default implementation__ for an interface method: ``` public interface IControl { void Paint() => Console.WriteLine("Default Paint method"); } public class SampleClass : IControl { // Paint() is inherited from IControl. } ``` The following sample invokes the default implementation: ``` var sample = new SampleClass(); //sample.Paint();// "Paint" isn't accessible. var control = sample as IControl; control.Paint(); ``` __Any class that implements the ``IControl`` interface can override the default Paint method__, either as a public method, or as an explicit interface implementation. default implementation method 可以被 overrided!! --- ## [Interface Properties (C# Programming Guide)](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/interface-properties) __Properties can be declared on an interface__. The following example declares an interface property accessor: ``` public interface ISampleInterface { // Property declaration: string Name { get; set; } // read-write string County { get; } // read-only string Grade { set; } // write-only } ``` Interface properties __typically don't have a body__. The accessors indicate whether the property is __read-write, read-only, or write-only__. Unlike in classes and structs, __declaring the accessors without a body doesn't declare an auto-implemented property__. __Beginning with C# 8.0, an interface may define a default implementation for members__, including properties. __Defining a default implementation for a property in an interface is rare because interfaces may not define instance data fields__. ## Example In this example, the interface ``IEmployee`` has a __read-write__ property, ``Name``, and a __read-only__ property, ``Counter``. The class ``Employee`` implements the ``IEmployee`` interface and uses these two properties. The program reads the name of a new employee and the current number of employees and displays the employee name and the computed employee number. You could use the fully qualified name of the property, which references the interface in which the member is declared. For example: ``` string IEmployee.Name { get { return "Employee Name"; } set { } } ``` The preceding example demonstrates __Explicit Interface Implementation__. For example, if the class ``Employee`` is implementing two interfaces ``ICitizen`` and ``IEmployee`` and both interfaces have the ``Name`` property, __the explicit interface member implementation will be necessary__. That is, the following property declaration: ``` interface IEmployee { string Name { get; set; } // read-write int Counter { get; } // read-only } public class Employee : IEmployee { public static int numberOfEmployees; private string _name; public string Name // read-write instance property { get => _name; set => _name = value; } private int _counter; public int Counter // read-only instance property { get => _counter; } // constructor public Employee() => _counter = ++numberOfEmployees; } ``` ### [out (generic modifier) (C# Reference)](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-generic-modifier) ### [in (Generic Modifier) (C# Reference)](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-generic-modifier) ### https://stackoverflow.com/questions/10956993/out-t-vs-t-in-generics ---- [start] temp - --- # [C# - Delegates](https://www.tutorialspoint.com/csharp/csharp_delegates.htm) C# delegates are similar to __pointers to functions__, in C or C++. A delegate is a __reference type variable__ that holds the reference to a method. The reference can be changed at runtime. reference type, to a method --> 有點像 block (kotlin) java 8 也有 method reference Delegates are especially used for __implementing events and the call-back methods__. All delegates are implicitly derived from the System.Delegate class. ## Declaring Delegates Delegate declaration determines the methods that can be referenced by the delegate. A delegate can refer to a method, which has the same signature as that of the delegate. For example, consider a delegate − ``` public delegate int MyDelegate (string s); ``` The preceding delegate can be used to reference any method that has a single string parameter and returns an int type variable. 只要單一字串參數,並回傳int 的 method, 都可套用該 delegate!! --> 不限哪一個 method Syntax for delegate declaration is − ``` delegate <return type> <delegate-name> <parameter list> ``` ## Instantiating Delegates __Once a delegate type is declared, a delegate object must be created with the ``new`` keyword and be associated with a particular method__. When creating a delegate, the argument passed to the new expression is written similar to a method call, but without the arguments to the method. For example − ``` public delegate void printString(string s); ... printString ps1 = new printString(WriteToScreen); printString ps2 = new printString(WriteToFile); Following example demonstrates declaration, instantiation, and use of a delegate that can be used to reference methods that take an integer parameter and returns an integer value. ``` --- # [C# - Events](https://www.tutorialspoint.com/csharp/csharp_events.htm) --- ``Func`` 系列類似 RxJava [Function](http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/functions/Function.html) ``` public interface Function<T,R> { R apply(T t); } ``` ## [Func<out TResult>](https://docs.microsoft.com/zh-tw/dotnet/api/system.func-1?view=netcore-3.1) ``` public delegate TResult Func<out TResult>(); ``` ## [Func<in T,out TResult>](https://docs.microsoft.com/zh-tw/dotnet/api/system.func-2?view=netcore-3.1) ``` public delegate TResult Func<in T,out TResult>(T arg); ``` * Object <- Delegate <- Func<T,TResult> ``` // Declare a Func variable and assign a lambda expression to the // variable. The method takes a string and converts it to uppercase. Func<string, string> selector = str => str.ToUpper(); // Create an array of strings. string[] words = { "orange", "apple", "Article", "elephant" }; // Query the array and select strings according to the selector method. IEnumerable<String> aWords = words.Select(selector); // Output the results to the console. foreach (String word in aWords) Console.WriteLine(word); /* This code example produces the following output: ORANGE APPLE ARTICLE ELEPHANT */ ``` --- Enumerable.Select 方法 public static System.Collections.Generic.IEnumerable<TResult> Select<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,int,TResult> selector); --- # using block ## [using statement (C# Reference)](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement) Provides a convenient syntax that ensures the correct use of [IDisposable](https://docs.microsoft.com/en-us/dotnet/api/system.idisposable) objects. Beginning in C# 8.0, the using statement ensures the correct use of [IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/system.iasyncdisposable) objects. ``` string manyLines=@"This is line one This is line two Here is line three The penultimate line is line four This is the final, fifth line."; using (var reader = new StringReader(manyLines)) { string? item; do { item = reader.ReadLine(); Console.WriteLine(item); } while(item != null); } ``` --- ## [Using objects that implement IDisposable](https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/using-objects) The common language runtime's garbage collector reclaims the memory used by managed objects, but types that use unmanaged resources implement the IDisposable interface to allow the resources needed by these unmanaged resources to be reclaimed. When you finish using an object that implements IDisposable, you should call the object's IDisposable.Dispose implementation. You can do this in one of two ways: With the C# using statement (Using in Visual Basic). By implementing a try/finally block, and calling the IDisposable.Dispose in the finally. --- ## [Understanding the 'using' statement in C#](https://www.codeproject.com/Articles/6564/Understanding-the-using-statement-in-C) --- # Thread safe ### [ICollection.SyncRoot Property](https://docs.microsoft.com/en-us/dotnet/api/system.collections.icollection.syncroot?view=netcore-3.1) * Namespace: ``System.Collections`` * Gets an object that can be used to synchronize access to the ``ICollection``. ``` public object SyncRoot { get; } ``` ``` ICollection myCollection = someCollection; lock(myCollection.SyncRoot) { // Some operation on the collection, which is now thread safe. foreach (object item in myCollection) { // Insert your code here. } } ``` ### [List<T>.ICollection.SyncRoot Property](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.system-collections-icollection-syncroot?view=netcore-3.1) * Namespace: ``System.Collections.Generic`` * Gets an object that can be used to synchronize access to the ``ICollection``. --- ### [Source array was not long enough. Check srcIndex and length, and the array's lower bounds](https://stackoverflow.com/questions/57785475/source-array-was-not-long-enough-check-srcindex-and-length-and-the-arrays-low) #### Answer: __You're accessing the list by different threads__: You could lock the list with: ``` lock(listTotalCost) { listTotalCost.Add(temp.Value); } ``` Or use Concurrent collections. --- # Sealed class 與 Singleton --- ## [C# Sealed Keyword](https://www.tutlane.com/tutorial/csharp/csharp-sealed-keyword) In c#, ``sealed`` is a keyword that is used to __stop inheriting the particular class from other classes and we can also prevent overriding the particular properties or methods based on our requirements__. 防止某 class 被繼承 並且 methods 或 properties 不被 overrided!! 若寫過 Java, ``sealed`` 等於 ``final`` Generally, when we create a particular class we can inherit all the properties and methods in any class. In case, if you want to __restrict access of defined class and its members__, then by using a ``sealed`` keyword we can prevent other classes from inheriting the defined class. ### C# Sealed Class In c#, a ``sealed`` class can be defined by using a ``sealed`` keyword. As discussed, when we define a class with the ``sealed`` keyword, then we don’t have a chance to inherit that particular class. ``` sealed class Test { public string Name; public string Location; } public sealed class Test1 { public int Age; } sealed public class Test2 { // Implementation } ``` If you observe the above code snippet, we defined various classes with a ``sealed`` keyword to make sure that the defined classes are not inheritable to any class. In c#, we can use a ``sealed`` keyword before or after the access modifier to define sealed classes. ### C# Sealed Class Example Following is the example of using a ``sealed`` keyword to define sealed classes in c# programming language. The following are the various ways of defining sealed classes in c# programming language. If you observe above example, we defined a class ``Users`` with sealed keyword and we are trying to inherit the properties from ``Users`` class using ``Details`` class. When you execute the above c# program, we will get the result as shown below. compiler error: ``` class ``ie.developments.SimpleSealedFoo`` 'DerivedSealedFoo': cannot derive from sealed type 'SimpleSealedFoo' [HelloDotnet]csharp(CS0509) ``` ### C# Sealed Method or Property In c#, we can also use the ``sealed`` keyword on a method or property that overrides a ``virtual`` method or property in a base class to allow other classes to derive from base class but to prevent them from overriding specific virtual methods or properties. Following is the example of using a ``sealed`` keyword on a method that overrides a virtual method in a base class. ``` using System; namespace Tutlane { public class A { public virtual void GetInfo() { Console.WriteLine("Base Class A Method"); } public virtual void Test() { Console.WriteLine("Base Class A Test Method"); } } public class B : A { public sealed override void GetInfo() { Console.WriteLine("Derived Class B Method"); } public override void Test() { Console.WriteLine("Derived Class B Test Method"); } } public class C : B { // Compile time error public override void GetInfo() { Console.WriteLine("Age: {0}", base.age); } public override void Test() { Console.WriteLine("Derived Class C Test Method"); } } class Program { static void Main(string[] args) { C c = new C(); c.GetInfo(); c.Test(); Console.WriteLine("\nPress Enter Key to Exit.."); Console.ReadLine(); } } } ``` ### C# Sealed Keyword Features The following are the important points which we need to remember about the ``sealed`` keyword in c# programming language. * In c#, to apply a ``sealed`` keyword on method or property, it must always be used with override. * In c#, we should not use abstract modifier with sealed class, because an abstract class must be inherited by a class that provides an implementation of the abstract methods or properties. * In c#, the local variables cannot be sealed. * In c#, structs are implicitly sealed, they cannot be inherited. sealed method/ property 要與 override 一起用 class 若是宣告 abstract, 不能用 sealed 只有 properties / methods 可以用 sealed; 區域變數不行 structre 本質上就是 sealed,所以不能被繼承 --- ## [Singleton Design Pattern In C#](https://www.c-sharpcorner.com/UploadFile/8911c4/singleton-design-pattern-in-C-Sharp/) ### What is Singleton Design Pattern? Singleton design pattern in C# is one of the most common design patterns is software design. In singleton design pattern ensures a class has only one instance in the program and provides a global point of access to it. A singleton is a class that only allows a single instance of itself to be created and usually gives simple access to that instance. Most commonly, singletons __don't allow any parameters to be specified when creating the instance since the second request of an instance with a different parameter could be problematic__. If the same instance should be accessed for all requests __with the same parameter then the factory pattern is more appropriate__. There are various ways to implement a singleton pattern in C#. The following are the common characteristics of a singleton pattern. * A single constructor, that is private and parameterless. * The class is sealed. * A static variable that holds a reference to the single created instance, if any. * A public static means of getting the reference to the single created instance, creating one if necessary. singleton, 只有單一 private constructor, 且沒任何參數 本身是 sealed class 有一個 static 變數 存放變 instance (reference) 一個 public static method 來存取該 reference ### Singleton class vs. Static methods The following compares Singleton class vs. Static methods: * A Static Class cannot be extended whereas a singleton class can be extended. * A Static Class can still have instances (unwanted instances) whereas a singleton class prevents it. * A Static Class cannot be initialized with a STATE (parameter), whereas a singleton class can be. * A Static class is loaded automatically by the CLR when the program or namespace containing the class is loaded. ### How to Implement Singleton Pattern in C# code There are many ways to implement a Singleton Pattern in C#. * No Thread Safe Singleton. * Thread-Safety Singleton. * Thread-Safety Singleton using Double-Check Locking. * Thread-Safe Singleton without using locks and no lazy instantiation. * Fully lazy instantiation. * Using .NET 4's Lazy<T> type. ### 1. No Thread Safe Singleton Explanation of the following code: 1. The following code is not thread-safe. 2. Two different threads could both have evaluated the test (if instance == null) and found it to be true, then both create instances, which violates the singleton pattern. 3. Note that in fact the instance may already have been created before the expression is evaluated, but the memory model doesn't guarantee that the new value of instance will be seen by other threads unless suitable memory barriers have been passed. ``` // Bad code! Do not use it! public sealed class Singleton { //Private Constructor. private Singleton() { } private static Singleton instance = null; public static Singleton Instance { get { if (instance == null) { instance = new Singleton(); } return instance; } } } ``` ### 2. Thread Safety Singleton Explanation of the following code: 1. This implementation is thread-safe. 2. In the following code, the thread is locked on a shared object and checks whether an instance has been created or not. 3. This takes care of the memory barrier issue and ensures that only one thread will create an instance. 4. For example: Since only one thread can be in that part of the code at a time, by the time the second thread enters it, the first thread will have created the instance, so the expression will evaluate to false. 5. The biggest problem with this is performance; performance suffers since a lock is required every time an instance is requested. ``` public sealed class Singleton { Singleton() { } private static readonly object padlock = new object(); private static Singleton instance = null; public static Singleton Instance { get { lock (padlock) { if (instance == null) { instance = new Singleton(); } return instance; } } } } ``` ### 3. Thread Safety Singleton using Double Check Locking Explanation of the following code: In the following code, __the thread is locked on a shared object__ and checks whether an instance has been created or not with double checking. ``` public sealed class Singleton { Singleton() { } private static readonly object padlock = new object(); private static Singleton instance = null; public static Singleton Instance { get { if (instance == null) { lock (padlock) { if (instance == null) { instance = new Singleton(); } } } return instance; } } } ``` ### 4. Thread Safe Singleton without using locks and no lazy instantiation Explanation of the following code: 1. The preceding implementation looks like very simple code. 2. This type of implementation __has a static constructor__, so it executes only once per Application Domain. 3. It is __not as lazy as the other implementation__. ``` public sealed class Singleton { private static readonly Singleton instance = new Singleton(); // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static Singleton() { } private Singleton() { } public static Singleton Instance { get { return instance; } } } ``` ### 5. Fully lazy instantiation Explanation of the following code: 1. Here, instantiation is triggered by the first reference to the static member of the nested class, that only occurs in Instance. 2. This means the implementation is fully lazy, but has all the performance benefits of the previous ones. 3. Note that __although nested classes have access to the enclosing class's private members, the reverse is not true, hence the need for instance to be internal here__. 4. That doesn't raise any other problems, though, as the class itself is private. 5. The code is more complicated in order to make the instantiation lazy. ``` public sealed class Singleton { private static readonly Singleton instance = new Singleton(); // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static Singleton() { } private Singleton() { } public static Singleton Instance { get { return instance; } } } ``` --- # [ref Keyword in C#](https://www.tutorialsteacher.com/articles/ref-keyword) C# supports value type and reference type data types. By default, the value type variable is passed by value, and the reference type variable is passed by reference from one method to another method in C#. value type 一般是傳值 reference type 是傳 reference Example: Passing Value Type Variable: ``` using System; public class Program{ public static void Main(string[] args) { int myNum = 10; // pass value type ProcessNumber(myNum); Console.WriteLine(myNum); Console.ReadLine(); } public static void ProcessNumber(int num) { num = 100; } } ``` In the above example, the value type variable ``myNum`` is passed by value. So, __changes in the ``ProcessNumber()`` method does not get reflected to ``myNum``__, whereas the reference type variable ``myStr`` is passed by reference to the ``ProcessString()`` method. So, any changes in the ``ProcessString()`` method will be reflected. We __sometimes need to pass the value type variables by reference__. So, how to do it? 傳 value type, 卻想以 reference 方式來傳遞 C# includes ``ref`` and out are keywords, which help us to pass the value type variables to another function by the reference. The following example demonstrates passing a value type variable by reference using the ``ref`` keyword. Example: Passing Value Type by Reference ``` class Program{ static void Main(string[] args) { int myNum = 10; ProcessNumber(ref myNum); //use ref to pass the parameter by reference Console.WriteLine(myNum); Console.ReadLine(); } public static void ProcessNumber(ref int num) { num = 100; } } ``` As you can see in the above example, the ``ProcessNumber()`` method specifies an ``int`` parameter with the ``ref`` keyword, so we must use the ``ref`` keyword while passing this parameter while calling ``ProcessNumber()`` method. A variable must be assigned a value before passing as an argument with the ``ref`` keyword. 傳遞參數時,也要加入 ``ref`` keyword We must specify the ``ref`` keyword when passing to the method. Otherwise, it will give a compile-time error. ``` static void Main(string[] args) { int myNum = 10; ProcessNumber(myNum); //Compile-time Error: Must use ref keyword Console.WriteLine(myNum); Console.ReadLine(); } public static void ProcessNumber(ref int num) { num = num + 100; } ``` The method can include other parameters with the ``ref`` parameter, as shown below. ``` static void Main(string[] args) { int myNum = 10, val=0; ProcessNumber(ref myNum, val); Console.WriteLine(myNum); Console.ReadLine(); } public static void ProcessNumber(ref int num, int val) { num = num + val; } ``` --- # [Boxing and Unboxing Operations in C#](https://www.pluralsight.com/guides/boxing-autoboxing-operations-csharp) ## What are Boxing and Unboxing? The C# programming language contains three different types of data: primitive types (i.e. value types) like ``int`` and ``char``, object types (i.e. reference types), and pointers. __Boxing__ and __unboxing__ deal with two of these data types, primitives and objects. __Boxing is the process of converting a primitive type into an object type__. You can find an example of boxing in the example code block below. value type and reference types 之間轉換 Boxing: value type -> reference type Unboxing: reference type -> value type ``` int sampleNumber = 5; //assignment statement Object ob = sampleNumber; //boxing ``` __Unboxing__, on the other hand, is the process of converting an object type into a primitive type__. You can find an example of both boxing and unboxing in the example code block below. ``` int sampleNumber = 5; //assignment statement Object ob = sampleNumber; //boxing int num = (int)ob; //unboxing ``` Boxing and unboxing are both important concepts in the field of object oriented programming. They enable a primitive type of data to be handled as an object, and vice versa. This is one of the building blocks of the unification of the Type System, which was implemented for the C# programming language. It allows different types of data to be used interchangeably by conversion, as long as it's a conversion that is allowed by the compiler (for example, a conversion from an ``int`` to a ``short`` is not allowed by the compiler). ## What Happens During Boxing and Unboxing Now that we know the definitions of these two concepts, we should next find out what is actually happening when you box or unbox a variable in C#. First off, when you box a variable, you are __wrapping the value into an object instance__. When boxing, you are performing an __implicit conversion__ from a primitive type to an object type. This means that when this code is run, the compiler will run an automatic type conversion. Simply put, the compiler will "promote" the value type to its reference type in order to prevent possible loss of data. An example of this would be __an ``int`` being converted to an ``System.Int32`` object by the compiler__. Also, when __this variable is converted to an object, it will be stored on the heap rather than on the stack__ with the other primitive types because since it's an object, it will __need dynamic memory allocation__. 把值包入 (wrapping) 一個物件 ``int`` --> ``System.Int32`` object reference type 放在 heap, value type 放在 stack When you unbox a variable, you are unwrapping an object type to a primitive type. When unboxing, you are performing an __explicit conversion__ from an object type to a primitive type. This means that you are basically giving the compiler a specific instruction to perform this conversion because you need to tell the compiler that you wish to imply a different interpretation of this variable than the compiler would normally expect. 把值反解包 (unwrapping) 變回純 value type It is important to note that while boxing a variable, if you change the value of the original primitive variable after boxing it into an object, the newly assigned value will not persist into the new object. An example of this is in the following code block. ``` int sampleNumber = 5; //assignment statement Object ob = sampleNumber; //boxing sampleNumber = 10; Console.WriteLine("Value of sampleNumber: " + sampleNumber); Console.WriteLine("Value of sampleNumberObj: " + sampleNumberObj); ``` > Value of sampleNumber: 10 Value of sampleNumberObj: 5 Looking at the output, you can see that the value of ``sampleNumberObj`` will change in the assignment statement, but then will not change when ``sampleNumber`` is updated. --- # [It Is What It Is and As It Is: Using the Is and As Operators in C#](https://www.pluralsight.com/guides/csharp-is-as-operators-is-expressions) ## Is Operator The ``is`` operator will __check if the result of the expression is compatible with a given type__ by simply testing an expression against a pattern. It is sometimes called __the operator of type testing__, and it will check whether the runtime type of an expression's result is compatible with a given type. The test against patterns came to C# as a feature with version 7.0. ``` public class Student { } public class Teacher { } Student s = new Student(); Teacher t = new Teacher(); bool isTeacher1 = s is Teacher; bool isTeacher1 = t is Teacher; ``` ## As Operator The ``as`` operator is used to __perform conversions between compatible types__. It has a very similar role to the ``is`` operator, however, it works differently under the hood. Note that it does not throw an exception when we have an incompatible type, we just simply don't have any value associated with the s variable, which evaluates to null. ``` public class Student { } public class Teacher { } Student s = new Student(); Teacher t = new Teacher(); bool isTeacher1 = s is Teacher; bool isTeacher1 = t is Teacher; string s_str = "Student" string t_str = "Teacher" Teacher tmp1 = t as Teacher; if (null != tmp1) { } Teacher tmp2 = t_str as Teacher; if (null != tmp2) { } ``` ## Differences Between ``As`` and ``Is`` The ``is`` operator is used to __check if the run-time type of an object is compatible with the given type or not__, whereas the ``as`` operator is used to __perform conversion between compatible reference types or nullable`` types__. The ``is`` operator is of __Boolean type__, whereas the ``as`` operator is not. The ``is`` operator __returns ``true`` if the given object is of the same type__, whereas the ``as`` operator __returns the object when they are compatible with the given type__. The ``is`` operator returns ``false`` if the given object is not of the same type, whereas the ``as`` operator __returns ``null`` if the conversion is not possible__. ``as`` 要嘛轉出預期的 data type (成功) 或 null type (失敗) The ``is`` operator is used for only reference, boxing, and unboxing conversions, whereas the ``as`` operator is used only for nullable, reference, and boxing conversions. ## [Casting and type conversions (C# Programming Guide)](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions) --- # [Knowing When to Use Override and New Keywords (C# Programming Guide)](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords) In C#, a method in a ``derived`` class can __have the same name as a method in the ``base`` class__. You can specify how the methods interact by using the ``new`` and ``override`` keywords. __The ``override`` modifier extends the base class ``virtual`` method__, and the ``new`` modifier __hides an accessible base class method__. The difference is illustrated in the examples in this topic. ``` public abstract class BaseLogger { public virtual void foo(string msg) { Console.WriteLine("Base - foo: {0}", msg); } public void bar() { Console.WriteLine("Base - bar"); } } public class LoggerA: BaseLogger { public override void foo(string msg) { Console.WriteLine("LoggerB - foo: {0}", msg); } public new void bar() { Console.WriteLine("LoggerA - bar"); } } public class LoggerB: BaseLogger { public override void foo(string msg) { Console.WriteLine("LoggerB - foo: {0}", msg); } } public class TestNewAndOverrideModifier: IRunnable { public void run() { BaseLogger AA = new LoggerA(); BaseLogger BB = new LoggerB(); AA.foo("Log started"); AA.foo("Log continuing"); AA.bar(); // involve BaseLogger's bar method ((LoggerA)AA).bar(); // involve LoggerA's bar method } } ``` --- # Overflow exception ## [overflow exception for int in C#?](https://stackoverflow.com/questions/2056445/no-overflow-exception-for-int-in-c) __C# ``integer`` operations don’t throw exceptions upon overflow by default__. You can achieve that via the project settings, or by making the calculation ``checked``: ``` int result = checked(largeInt + otherLargeInt); ``` Now the operation will throw. The opposite is ``unchecked``, which makes any operation explicitly unchecked. Obviously, this only makes sense when you’ve got ``checked`` operations enabled in the project settings. Inside a ``checked`` block or expression, an ``OverflowException`` is thrown. If you don’t care about overflows, don’t check for them. Your checksum example would be a typical use-case where you don’t want to check for overflows. This will normally roll around (not go to zero). However, note that C# (and other languages) by default do something cheeky called “integer promotion”. The result of adding two bytes is an integer. If you print that directly, the result may be larger than what can fit inside a byte. You need to reassign it to a byte (or cast it) to truncate it. ## [OverflowException](https://docs.microsoft.com/en-us/dotnet/api/system.overflowexception?redirectedfrom=MSDN&view=netcore-3.1) 使用 ``check {}`` / ``uncheck {}`` blocks ``` int value = 780000000; checked { try { // Square the original value. int square = value * value; Console.WriteLine("{0} ^ 2 = {1}", value, square); } catch (OverflowException) { double square = Math.Pow(value, 2); Console.WriteLine("Exception: {0} > {1:E}.", square, Int32.MaxValue); } } // The example displays the following output: // Exception: 6.084E+17 > 2.147484E+009. ``` --- 如何使用 ``FileStream``, ``HttpClient`` 解析 json 如何用第3方套件 --- # Default [default value expressions (C# reference)](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/default) [Default(T) In Generics](https://www.c-sharpcorner.com/article/defaultt-in-generics/) --- # [Nested generic interfaces](https://stackoverflow.com/questions/14497854/nested-generic-interfaces)