Classic Questions Summary
There are several classic questions that include data structure and algorithm.
There are several classic questions that include data structure and algorithm.
Metadata and IL Language are the fundamentals of CLR. Metadata describes the static structure and IL Language
describes the dynamic execution.
Metadata is fundamental data that is used to describe other complex data.
For the .NET metadata, it is used to describe: class, type, property, method, filed, parameters, attribute. The main category of .NET metadata are:
Type | Name |
---|---|
Definition Form | TypeDef, MethodDef, FieldDef, ModuleDef, PropertyDef |
Reference Form | AssemblyRef, TypeRef, ModuleRef, MethodsRef |
Pointer Form | MethodPtr, FieldPtr, ParamPtr |
Heap | #String, #Blob, #US, #GUIDe |
Below is the metadata to describe the Main function of class Program
; |
Person person
: Reference typeinitobj
0
, and reference type of class to null
new Person()
: Value typenewobj
ctor
constructor methodInitialization of some special type
newobj
IL has two keywords to describe the method type.
static
keyword to declarecall
keyword to executeinstance
keyword to declarecallvirt
to executecall
: call the method according to the static type of the reference, mainly used for non-virtual method.Equals
, ToString
callvirt
: call the method according to the dynamic type (real object) of the reference, mainly used for virtual method.calli
: call the method through a method pointerIdftn
or Idvirtftn
command get the method pointerMethodInfo.Invoke()
and Dynamic Method DelegateSystem.Object
.ctor
method: class constructor method.cctor
method: class type constructor method.cs
to .exe
.dll
or .exe
.cs
to .il
.il
and .exe
.il
to .exe
.exe
to .il
ctrl + m
could view the metadata in that code.CTS defines the types and rules for different programming language based on .NET. It defines the relationship between each language with their IL program.
Like in C#, the type of int
, char
, string
corresponds to System.Int32
, System.Char
, System.String
.
The type in the content of CTS includes the following chart.
System
Primitive type in C# and FCL
C# | FCL |
---|---|
int | System.Int32 |
long | System.Int64 |
floaat | System.Single |
string | System.String |
object | System.Object |
int
, char
, long
, bool
, float
, double
, byte
, enum
, struct
.System.ValueType
(which inherits from System.Object
)Equals
method, could compare the value of two data instead of the addresses of two dataclass
, interface
, delegate
, object
, string
and int[]
etc.System.Object
String
is very special. The equals of string will compare the value instead of the address. Every action on the string will generate a new string data in the managed heap.ref
, out
)static public implicit operator XX(YY y)
to write a method can customize the convert between different typeFor the convert between value type and reference type, we need to use boxing (from value to reference) and unboxing (from reference to value) to achieve it.
Note. unboxing must happen in the reference type which is generated from boxing process.
The boxing and unboxing will influence the efficiency. Use generic could avoid influencing the efficiency.
Examples of boxing and unboxing
Value Type | Reference Type | |
---|---|---|
Value Passing | Inner change won’t influence outside | Inner assign action influences outside, but the initialization won’t influence outside |
Reference Passing | Any change will influence outside | Any change will influence outside |
For reference passing, must use ref
or out
ref
: must be initialized before passingout
: must be initialized inside method.NET CLR has 3 part of memory.
When call an instance method. The next command will be pushed to stack of thread
, then other local value type will be pushed to the stack. When finish, those value type will be pop until get the pointer to the next command.
GC Heap
stores the instance of reference type. Manged by GC. The instance will contains a TypeHandler
which points to its method table in the Loader Heap.
Loader Heap
stores the metadata (type). Every type in the loader heap is a method table. Managed by AppDomain. The method table has a part called Method Slot Table
, which is a linked list containing the methods. When call a method in a reference type (class), CLR will follow the TypeHandler
in the GC heap to find the metadata which contains this type’s definition in Loader Heap. Then CLR will check the Method Slot Table
in this method table, and use JIT to compile the method’s IL code to naive code. The naive code will be stored in a dynamic memory.

: return the non-null object. Check A firstlyExplicit
public static explicit operator XX(para)
Implicit
public static implicit operator XX(para)
#if
, #else
, #elif
, #endif
[Conditional("Debug")]
#define
, #undef
#define Debug
for the conditional compile#warning
, #error
#region
, #endregion
#pragma
checked
, unchecked
yield
yield return
is used to return a value in the enumerator. The return type of the method belongs to System.Collections.Generic.IEnumerator<T>
, System.Collections.IEnumerable
or etc.yield break
is used to end the enumerating.lock
lock(xx)
to add a lock for the xx object, so that if other threads want to call this object, they need to wait current thread to finish the process on this object.unsafe
*
, &
, sizeof
to avoid the CLR and operate the memorysealed
override
keyword togetherType
Name
: type nameProperty Name
: type name containing the namespaceAssemblyQualifiedName
: type name containing the namespace and assemblyconst
or readonly
values are assigned a value, the value couldn’t be changed. const
new
keywordreadonly
or static readonly
Class
Struct
new
to instantiate
Actually they have no relationship to each other.
Attribute
System.Attribute
[]
, support multi attribute[AttributeUsage()]
: Control how to apply customized attributes to targeted element[Flags]
: Regard the value of enum as bit flag rather than value[DllImport()]
: Call the un-managed code. e.g. Win32 API method[Serializable]
: Indicate the element could be serialized[Conditional()]
: Support the conditional compileProperty
See here for more info.
Class can implement interfaces and inherit another class.
Interface doesn’t inherit from System.Object
. Methods in an interface are abstract methods, so interface cannot be instantiated but only be implemented by other classes. Classes implement one interface need to implement all the abstract methods or properties in the interface. It supports the polymorphisn.
For abstract class, it also contains the abstract methods and the abstract class cannot be instantiated but only be inherited. Classes which inherits a abstract class need to implement all the abstract methods. Apart from the abstract methods, the abstract class can also include some public and virtual methods which contains the body. So the subclass can use those methods directly. It supports the polymorphisn.
Some use cases are as follow.
Interface | Abstract Class |
---|---|
Provide common method for unrelated classes | Provide common elements for related classes |
Defines the action | Defines the properties, pre-defined methods, common fields |
Usually not change after create | Can be used in multi-version scenarios |
Subclass converting to base class can be achieved implicitly, while base class converting to subclass needs to be achieved explicitly.
is
: Is used to determine whether this type can be converted to another type. Return false is object is null.as
: Convert the type. Return null if object is null.override | overload |
---|---|
For subclass to override the virtual/abstract method in base class | In one class, contains several methods with the same name |
method name and parameters and return type should be same | methods with the same name but with different parameters list |
Dynamic binding. Method calling is confirmed in CLR. CLR will check the proper method for a base class reference according to type of its instance | Static binding. Method calling is confirmed in the compile |
For override the generic method, the constrains of generic method in base class will be inherited. | Generic method could also serve as the overload method |
Use =
for value type is deep copy; Use =
for reference type is mainly shallow copy. (String is deep copy)
Inherit interface ICloneable
to customize the Object Clone()
method. e.g. return a new object
Use static field to define a Singleton
class.
Static | Non-static | |
---|---|---|
Class | Only contains static field and static method Cannot be instantiated |
Can contains static method and non-static method Can be instantiated |
Method | Can only use static field and static method | Can use any field and method |
Dynamic
is the keyword and a class. It can be used for field, property, method, indexer, parameters, return value, local variable. The specific type of the element declared dynamic
will be determined during the CLR/DLR.
var | dynamic | System.object |
---|---|---|
type will be determined during compile | type will be determined in CLR/DLR | a instance type |
only ca be used for local variable | can be used for everything | can be used for everything |
Dynamic
solve the dynamic bind for objects. It combines C# with other dynamic language like IronPython, IronRuby.
1 | ScriptRuntime py = Python.CreateRuntime(); |
Dynamic
can also dynamically add a filed or property to a class.
Object
is the top base class for any other classes in .NET C#. The base methods of System.Object
contains:
GetMembers
and GetMethods
to get the instance of this typepublic virtual bool Equals(object obj)
GetHashCode
the same timepublic static bool Equals(object objA, object objB)
public static bool ReferenceEquals(object objA, object objB)
: compare whether 2 objects are points to the same instance==
Note: String
is a very special type.
There are two kinds of constructors. Their IL forms are as follow.
.ctor
: object constructor.cctor
: type constructor (static constructor).NET also provide a flexible constructor to allow to set the properties in the constructors.
1 | User user = new User {Name = "aa", Age = "bb"}; |
String is a sealed class. It is a reference type but shows value type features when using.
Immutability. Once a string is created in the memory, it cannot change. Any actions including Insert, Substring, ToUpper will create a new string.
String interning. When the CLR loads, it will create a resident pool. This pool won’t be controlled by GC or Every unique string value in code will store in this resident pool. CLR will also create a hash map, the key is the string stored in resident pool and the value is the address. When creating a string value by assigning a unique value, it will store that value in resident pool and assign the address to this string. When assigning a value appeared before, CLR will assign the address checking from hash map to this string.
Note. If a string is assigned dynamically e.g. assigned by other string, the result value of this string won’t be stored in the resident pool. Use System.Intern(xx)
can add it to resident pool.
For convert. Some value types already override the ToString
method for converting itself to a string. To convert a string to other value types. e.g. Double.Parse(str)
, Double.TryParse(str, out num)
, num = Convert.ToDouble(str)
StringBuilder
can help to append several strings and convert to a string together.
System.Enum inherits from System.ValueType. Default, the first element equals to int 0
. The value of the element can also equals to bit number 0x00
if the attribute [Flags]
is added to the enum. At this time, a enum variable supports the |
operation.
Common methods contain
GetNames(typeof(X))
: Get all names of the enumGetValues(typeof(X))
: Get all value of the enumIsDefined(typeof(), XX)
: Check whether the name of value in the enumCollection is a container to control a bunch of objects. The collection can be treated as a whole object and every object can also be get separately.
Collection is a class in .NET. The common methods for most collections types include:
Method | Function |
---|---|
Add | add new item |
Insert | insert new item in a specific index |
Remove | remove a particular item |
Clear | remove all items |
IndexOf/LastIndexOf | find the index of a particular item |
Sort | sort items |
GetEnumerator | return value when iterated calling |
Count | the count of all items |
Item | get a specific item |
For a collection, it should implement the IEnumerator interface, which support MoveNext
and Reset
methods, and Current
property. Then in C#, users can use foreach
to get the value from the enumerator.
For a collection, it should implement the Synchronized method, which support for the safe action on the object in the multi-thread code.
The category of collections include:
ICollection
Stack
Stack<T>
Queue
Queue<T>
IList
Array
ArrayList
List<T>
IDictionary
Hashtable
Dictionary<TKey, TValue>
SortedDictionary
SortedList
SortedList<T>
For customized collection, users can inherit the CollectionBase
abstract class or implement interfaces like ICollection
, IList
.
Delegate is a class which implements a safe type callback method. Delegate is like the method pointer in C++. It defines the return type and parameters list. A delegate type needs to be instantiated and then added other methods. By calling this delegate directly or use its Invoke
method, it could callback other methods added to this delegate.
For multi-methods added to the delegate, it is called multicast. Methods could use +=
or -=
to bind or unbind to the delegate. The order of callback those methods is the same with the order to bind to the delegate.
There is some pre-defined delegate in C#, which include
Event model is also based on delegate. It is a encapsulation for delegate. See here for more examples about delegate and event.
Anonymous method is a method without name but have the expression body.
Delegate
keyword can be used to declare an anonymous method. The anonymous method can be assigned to a delegate variable.
1 | delegate void MyDelegateType(int x, int y); |
Lambda Expression can also be used to declare an anonymous method. The form is Argument => expression
or (Arguments) => {expression}
. Compared with using delegate to declare anonymous method, it don’t required to declare the type of the arguments because the compiler will set the type automatically.
1 | MyDelegateType myDelegateInstance = |
1 | public class test<T> {} |
T
isn’t assigned a specific type T
is value type, JIT will generate different naive code by replace the T
with different value typesT
is reference type, there will only be one copy of naive codeSystem.Collections.Generic
List<T>
SortedList<TKey, TValue>
Queue<T>
Stack<T>
Collection<T>
Dictionary<TKey, TValue>
When instantiate a parameterized type field, the default
keyword can be used, which will return 0
for value type and null
for reference type.
1 | public class test<T> |
The generic can use where
keyword to add constraints for the parameterized type.
1 | public class test<T> where T: constraint1, constraint2, ... |
Constraint | Function |
---|---|
T: struct | The type T must be value type |
T: class | The type T must be reference type |
T: class name | The type T must be the named class or its derived class |
T: interface | The type T must contains or implement those interfaces. The interfaces could also be generic interfaces |
T: new() | The type T must contain a constructor without parameters |
Generic method can exist in a generic class or a non-generic class.
1 | class MyClass{ |
Interface can also have generic features. Some generic collections class implements those generic interfaces. e.g. IList<T>
, IComparable<T>
1 | class MyArray<T>: IComparable<T> {} |
Delegate can also have generic features. e.g. delegate string MyMethod<T>(T t)
.
Generic delegate can also use for event. Like EventHandler<TEventArgs>
. It is defined as delegate void EventHandler<TEventArgs>(object sender, TEventArgs e)
1 | using System; |
EventHandler<TEventArgs>
for event definitionNullable<T>
for handling null conditionIEnumerable<T>
for achieving enumeratorSystem.Object
or System.Type
try
catch
or finally
catch
System.Exception
DivideByZeroException
StackOverflowException
FileNotFoundException
throw
to throw the exceptionfinally
System.Exception
is a class, which contains
Safety models structure of .NET
IPrincipal
IsInRole
and Identity
GenericPrincipal
for generic users and WindowsPrincipal
for Windows users.IIdentity
AuthenticationType
, IsAuthenticated
, and Name
GenericIdentity
, WindowsIdentity
, FormsIdentity
for ASP.NET application and PassportIdentity
which requires Passport SDK.PrincipalPermissionAttribute
or PrincipalPermission
class to declarative or explicitly check the accessFileIOPermission
EnvironmentPermission
EventLogPermission
Demand
, LinkDeman
, Assert
to declarative or explicitly check the access.NET Framework includes CLR (Memory Management, Thread Management and Remote Process) and FCL, which is a object-oriented collection of reusable types. FCL needs to provide API for program and it provides a tree type structure. FCL assemblies is stored as .dll
files in disks.
The node of the FCL structure is called namespace, which contains class
, struct
, enum
, delegate
, interface
. The namespace is only the logic structure of the FCL structure rather than the physical structure of the assembly. The same namespace could stored in different assemblies. Common namespace are as follows.
System namespace contains many basic data type. It includes
Object
ValueType
Int16
, Int32
, Char
, Boolean
, Double
String
Array
Delegate
Attribute
Type
Nullable
It also includes many basic services
It contains handle for the file, folder and memory stream.
It is related to the serialization (convert object to a saveable or transmittable format) and deserialization (recover the object from physical material or stream).
BinaryFormatter
SoapFormatter
XmlSerializer
Handle the system process, event log and help to debug.
Asynchronous method is implemented in C# by using async/await
keywords.
That’s the goal of asynchronous: enable code that reads/writes like a sequence of statements, but executes in a much more complicated order based on external resource allocation and when tasks complete.
Without language support, writing asynchronous code required callbacks, completion events, or other means that obscured the original intent of the code. In C#, keywords async
and await
are used to achieved a asynchronous program. The function return immediately when it meets a await
. A code sample is like following.
1 | using System; |
How to code executed:
method1
, then encounter await
, get back to the main functionmethod2
, then encounter await
, get back to the main functionNote. the step 4 and 5 won’t output if we don’t add the ReadKey
method in the end because the main thread will ends and those asnyc methods still in the same thread thus end, too.
In IL, we find that the compiler generate 2 classes for Method1 and Method2 called <Method1>d__0
and <Method2>d__1
. The two classes are state machines, the implement the interface TStateMachine
. The class contains the following elements.
int
stateTestAsync
thisAsyncVoidMethodBuilder
builderTaskAwaiter
u__1int
5__1 (the local int i
in for loop).ctor
There are two important data types. System.Runtime.CompilerServices.AsyncVoidMethodBuilder
and System.Runtime.CompilerServices.TaskAwaiter
Create
method will return a instance of the builderStart<TStateMachine>
method will begin running the builder with the associated state machineFor the Method2 itself, the IL code is as follows
Once we call the Method2, it does the following things.
<Method2>d__1
. <Method2>d__1::this
AsyncVoidMethodBuilder::Create<<Method2>d__1>
to create a async void instance for the state machine<Method2>d__1::state
to -1AsyncVoidMethodBuilder.Start
, the passing state machine is the class <Method2>d__1
<Method2>d__1::MoveNext
, since the state is -1, output the str, and change state to 05__1
field as 0, then call the Task.Delay
method, and get awaiter for this task and set it to u__1
fieldu__1::IsCompleted
. If haven’t finish, call AsyncVoidMethodBuilder::AwaitUnsafeOnCompleted<5__1, <Method2>d__1>
, which will call <Method2>d__1::MoveNext
method when the status of the awaiter is complete<Method2>d__1::MoveNext
to 5__1::UnsafeOnCompleted(Action)
Async methods can have the following return types
| void | Task | Task<TResult>
—–|——|——|—————
has return statement | No | Yes | Yes
return statement type | - | Task | Task<TResult>
can assign to delegate or event | Yes | Yes | Yes
can assign to Task | No | Yes | Yes
caller can know whether this method has completed (create a awaiter for it) | No | Yes | Yes
its awaiter has return statement | - | No | Yes
its awaiter return type | - | - | TResult
Compared to execute a thread to do actions, the Task
class is used to execute asynchronously, and it can track the status of this asynchronous action, including whether it finish and what is the return value. Most commonly, a lambda expression is used to specify the work that the task is to perform.
For operations that return statement, the Task<TResult>
class will be used.
1 | using System; |
In the mMain1 method, the Method1 and Method2 are still be executed in a synchronously. So the output is the same with the void-returning async method.
In the mMain2 method, we create the awaiter for the Method1 and Method2, so Method2 will be called after Method1, and Method3 will be called after Method2.
In the mMain3 method, we firstly run the Method1 and Method2 synchronously and assign them to Task and Task<TResult> variables. So the two methods will run at the same time. Then we use Task.WaitAny
and create a awaiter for Method2, so Method3 will run after Method1 and Method2.
Similarly, the complier will generate 2 state machine classes for Method1 and Method2 and 3 state machine for mMain1, mMain2, mMain3.
In the state machine of Method1 and Method2, it is similar to the void-returning async method but it uses AsyncTaskMethodBuilder<TResult>
classes to build the async task. In Method2, when it is finished, it uses SetResult(TResult)
method to marks the task as successfully completed and also pass the ReturnArgs
statement.
In the mMain2 and mMain3 state machines, there will be TaskAwaiter
class and TaskAwaiter<TResult>
result. After the awaiter’s property IsCompleted
is true, they will call TaskAwaiter<TResult>.GetResult
to get the return statement from the AsyncTaskMethodBuilder<TResult>
.
The Async function can be cancelled by passing a CancellationToken
parameter created by a CancellationTokenSource
.
1 | CancellationTokenSource tokenSource; |
Inheritance is a very important feature in C#. It can allow you to achieve the polymorphisn, which is very very important feature which could help you to write the code in a good design (easy to extend).
When class Student
inherits class Person
publicly. Those functions and members which are public and protected in class Person
can be used in class Student
. Functions and members which are private in class Person
cannot be used in class Student
.
However, if there is a public/protected function in class Person
, which uses the private members of class Person
. When class Student
call that functions, those private members in class Person
could also be used via this function.
Use base.function()
in the class Student
can call the functions implemented in class Person
(the functions should be public/protected). This is often used when class Student
rewrite the methods of class Person
but still need to call the method of class Person
.
Polymorphisn often happens when you declare a class Person
reference, but you point it to an object instantiated from class Student
.
When there is a abstract/virtual method in class Person
, class Student
could use override/new to rewrite that method. At this moment, call the which are rewrote can lead to charming results.
Since the abstract class can’t be instantiated, we just talked about those virtual - override/new relationship.
override
in subclass. Call this method from the reference is executing the method in subclass.new
in subclass. Call this method from the reference is executing the method in base class.If the method is declared abstract in base class. You cannot call it except the subclass override
this method.
1 | using System; |
1 | using System; |
This post is some ROS command from ROS tutorial.
This post talks about different level of Windows application development, including APIs, Application category, and hardware platform.
本文将简述.NET(包括.NET Framework, .NET Core等)和编程语言C#之间的关系。
.NET的命名就是因为.net是互联网中比较通用的一个域名后缀,因此.NET本身也是和通用相关的。
.NET是一个微软搭造的开发者平台,它主要包括:
在.NET的三部分内容中,编程语言和软件工具我们都比较清楚,那么技术框架体系中的具体内容都是什么呢?
下图是代码编译和运行的流程
框架库是一些用于描述数据类型的基础类型。比如Object
不仅是C#语言的类型根、还是VB等所有面向.NET的语言的类型根,它是整个FCL的类型根。同时.NET的框架库有单继承的特点。
WPF
which coupled with WindowsAndroid
、IOS
and macOS
C# is the programming language targeted to .NET. The version of C# is updated with the update of .NET implementations.
[1] https://www.cnblogs.com/1996V/p/9037603.html
[2] https://blog.csdn.net/MePlusPlus/article/details/76242330
[3] .NET Standard
Delegate and event are good ways to “subscribe” some actions to other particular actions carried out by the user or the code. It sounds like function 1 is executed firstly, then function 2, 3, and etc are executed following. Those functions may not in the same class.
For example, they are in class A, class B, class C. If we use the traditional ways to achieve this relationship, we need to call function 2 and 3 in the class A when the function 1 is executed. In this way we will increase the degree of coupling between these classes, that is class A cannot work normally without class B and C.
Therefore, we proposed the ideas of delegate and event. Class B and C could “subscribe” the action publisher in class A with their function 2 and 3. When the action 1 is executed, the class A will call the action publisher, then the class B and C will receive the information that action 1 is executed, so they will execute the action 2 and 3.
delegate | event |
---|---|
Functions can use += to subscribe it, and -= to unsubscribe it, and = to fully occupy the delegate | Only support += and -= |
Is a type, still need to instantiate a member | Is a variable instance |
Can be defined outside the class | Can only be defined inside the class |
Can be executed outside the class | Only can be executed in the class where it defines |
delegate is the member of the class (static member) | event belongs to the instance of a class |
Can be invoked outside the class | Cannot be invoked outside the class |
1 | event EventHandler<bool> OnEvent1; |
Delegate can be used to declare an anonymous method.
1 | event MyHandler<EventArgs> OnTrigger; |
See more about anonymous method from here
The delegate and event can both be used two methods to executed.
myDelegateInstance(paras)
or myEvent(paras)
myDelegateInstance.Invoke(paras)
or myEvent.Invoke(paras)
They are the same in compiler but the second method could add ?
to handle the null conditions.
myDelegateInstance?.Invoke(paras)
or myEvent?.Invoke(paras)
Start()
function.GetComponent
Transform
Find(string name)
Find(string name)
for a transform can only find the direct children of a transformWheel collider is a collider rather than the mesh of the wheel. You can add force or torque to the collider to make the collider rotate like a wheel.
Rigidbody has a element named velocity
, which can set the speed(Vector3) of the gameobject.
OnCollisionEnter
or OnTriggerEnter
Physics.OverlapSphere(point)
to detect whether the point collides with other colliders.Collider.Raycast
to get the accurate collision position. It will ignore other colliders but this collider.transform.root.gameObject
can find the root objectgameObject.GetComponentInChild()
can find the script attached to the child objects.transform.Find()
can find the children objects, but this is only used to find the direct children
objects.
Attributes of C# can add metadata (information about the types defined in a program) to the program. In Unity, it can be used to show information in Unity editor’s inspector.
The attributes work by placing the name of the attribute enclosed in square brackets ([]) above the declaration of the entity to which it applies. There are several different attributes in Unity
Name | Function |
---|---|
HideInInspector | Hide public parameter in Unity Inspector |
SerializeField | Show the private parameter in Unity Inspector |
Space | Show a space line in Unity Inspector |
Header(“XX”) | Show a comment for the parameter in Unity Inspector |
Range(min, max) | Show the value range in Unity Inspector |
Unity can use async/await
keywords of C# to achieve asynchronous methods, which can be found here.
However, some Unity library functions cannot be executed correctly in the asynchronous thread. Instead, Unity has its own asynchronous keyword, which is IEnumerator/yield return
.
yield return
keyword has many kinds of return type, which shows following
Type | Function |
---|---|
yield return new WaitForEndofFrame() |
Wait until the end of current frame |
yield return new WaitForFixedFrame() |
Wait until next frame |
yield return new WaitForSeconds(xx) |
Wait for xx seconds |
yield return new WaitForWhile(func) |
Wait until func return false |
yield return new WaitForUntil(func) |
Wait until func return true |
In Unity scripts, sometimes we need to do some actions after changing the properties of the GameObject, e.g. position, rotation. Unity will finish the changing action in the end of current frame. So we need to wait for a while before doing other actions.
Note. the event of delegate trigger is also finished in the current frame.
Also in Unity, we need to use yield return null
or allow the code return to the main thread to do some changes in the scene.
Note. don’t use yield return 0
because it is the same with yield return null
but it will lead to boxing action.
Unity has many targeted platforms, so the codes can be conditional complied according to this link
UnityEngine.dll
and mscorlib.dll
Mono
or IL2CPP
to build the IL scripts to naive code