📜 ⬆️ ⬇️

Some questions on .NET and C # (answers with analysis)

Last weekend I launched the post “Several Questions on .NET and C #”

I think many people are interested not only to find the right answers, but also to find out how many users know these correct answers. It is for this purpose that this post was created.

I do not insist on the truth of explanations in the last instance, therefore constructive criticism, additions and clarifications are welcome.
')


The promised answers with analysis under a cat.




This question made the most noise in the comments.

The C # specification says:
The static constructor for a class application. The Constructor is a triggered case.

An instance of the class is created.
Any of the static members are referenced.

Therefore, the closest answer to the truth is: " Once when you first create an instance of a class or when you first access static members of a class ." Although in this case, probably the reformulation of "... at the first mention" would be more appropriate.

The fact is that static constructors are explicit (when the constructor is specified explicitly) and implicit (the assignment of values ​​to static properties). In the case where there is no explicitly defined static constructor, the class is flagged with the beforefieldinit flag, which tells the CLR that the initialization of the static field will occur before the first reference to this field, and it can happen long before that reference.

By the way, on this property of the static constructor is built one of the implementations of Singleton.
 public sealed class Singleton { static readonly Singleton instance = new Singleton(); // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static Singleton() { } Singleton() { } public static Singleton Instance { get { return instance; } } } 





For similar purposes, the keywords add and remove are provided in C #. They must be used in the same way as get and set for properties, that is:

 public class MyClass { private EventHandler myEvent; public event EventHandler MyEvent { add { myEvent += value; } remove { myEvent -= value; } } } 



 int i = 5; object o = i; long j = (long)o; 

Most users do not know the correct answer to this question.

An InvalidCastException exception will be thrown (An exception that is thrown during an invalid cast or explicit type conversion). The error is in the third line.

Type casting is a conversion of a value of a variable of one type into a value of another type, which is explicit and implicit:
 int i = 123; long l = (long)i; // explicit int i = 123; long l = i; // implicit 

There are two types of types: value-type and reference-type (value-types and reference-types, respectively), at the moment when we assign a value to a variable with a reference type, a value occurs boxing (packaging) of this value.
This is a type of

The reverse process is called unboxing .

To correct the error, it is enough to change the third line long j = (int)o ; First, unboxing will be performed and a variable of type int will be returned, after which the corresponding implicit statement will be called.



Everything except the #typedef and #elseif directives .

+ UPD
Using #define you cannot write macros, as, for example, in C ++, but you can set values. Directives #if , #else , #endif check if the value is set. The Conditional attribute is used to instruct the compiler to compile or not compile the method, depending on whether the corresponding value of #define is set to exclude all calls to this method from the assembly. The method itself will remain in the assembly and you can call it using Reflection .

Conditional Example
 #define TRACE_ON using System; using System.Diagnostics; public class Trace { [Conditional("TRACE_ON")] public static void Message(string msg) { Console.WriteLine(msg); } } [Conditional("DEBUG")] public void Test() { MessageBox.Show("I want cookie"); } ctor() { this.Test(); this.GetType().InvokeMember("Test", BindingFlags.InvokeMethod, null, this, null); } 


-UPD


In C #, you can create nested namespaces either by writing their names through a dot, or by nesting one into the other using the compound operator { } .



To use unsafe code you need to call the compiler with the / unsafe key , this key can also be set in the project settings. In addition, each method with unsafe code must be marked with the unsafe keyword .



Consider an example with a button. By creating an object of class Button , we subscribe to its Click event, which occurs when a button is clicked. In this case, the Button object is the publisher ( publisher ), and the method that is subscribed to the event, respectively, the subscriber.



During compilation, the values ​​of the constants are substituted in the places of their use.


Most users do not know the correct answer to this question.

All of the listed elements can be found in the AttributeTargets enumeration type, whose values ​​are used in the AttributeUsage attribute, which is used to specify what can be tagged with an attribute.

An example of using an attribute applied to a return value:
 using System.Runtime.InteropServices; [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern Boolean MessageBeep(UInt32 uType); 




There is a special System.Runtime.InteropServices space in which there are classes for working with unmanaged code, for example, the well-known DllImport attribute for connecting DLL functions.



The Obsolete attribute indicates the entity not recommended for use. Each use of an entity that is deprecated will generate a warning or error depending on the settings of this attribute.

+ ADD
About the project settings in the question is not mentioned, then we take the default behavior. Attribute Attribute: [Obsolete]
On the method in this solution, without changing the properties of the solution, it will lead to a warning:
 public ObsoleteAttribute() { this._message = null; this._error = false; } 

-ADD

Details on MSDN



Structures do not support inheritance, but can implement interfaces. Also, one of the features is the impossibility of defining a default constructor, since fields are initialized with default values ​​automatically. But, however, it is possible to define a static constructor.

Source: https://habr.com/ru/post/172329/


All Articles