Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

31
Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang

Transcript of Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Page 1: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Effective C#50 Specific Way to Improve Your C#

Item 30,31

Effective C#50 Specific Way to Improve Your C#

Item 30,31

Scott68.Chang

Page 2: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

AgendaAgenda

• Chapter 4. Creating Binary Components

• Item 30: Prefer CLS-Compliant Assemblies

• Item 31: Prefer Small, Simple Functions

Page 3: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Chapter 4. Creating Binary Components

Page 4: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

.Net and CLR.Net and CLR

• The .NET environment is designed to support applications that consist of multiple binary components. – upgrade those components independently, – installing and upgrading one assembly in a multi-assembly

application.• The CLR loader

– determine what file gets loaded (strong- and weak-named assemblies)

– determines whether the assembly is already loaded into the current application context.

– search and load assembly

Page 5: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Loader searches sequence Loader searches sequence

• loader searches a set of predefined directories:– The application directory.

Ex: /FrameworkV2– The culture directory.

Ex: /FrameworkV2/en-US– The assembly subdirectory.

Ex1: /FrameworkV2/[assemblyname] Ex2: /FrameworkV2 /[culture]/[assemblyname]

– The private binpath. This is a private directory defined in the application config file.

Ex1: [binpath] Ex2: [binpath]/[assemblyname]

Page 6: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Strong NameStrong Name

• A strong name consists of four items:– text name of the assembly– version number – culture attribute– public key token

• Benefit:– components will be less likely to be replaced by malicious

components. – use config files to map the requested version to a new,

improved version of a component.

Page 7: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample: Strong NameSample: Strong NameIn assemblyInfo.cs

[assembly: AssemblyTitle("My Assembly")][assembly: AssemblyDescription ("This is the sample assembly")]#if DEBUG[assembly: AssemblyConfiguration("Debug")]#else[assembly: AssemblyConfiguration("Release")]#endif[assembly: AssemblyCompany("My company")][assembly: AssemblyProduct("It is part of a product")][assembly: AssemblyCopyright("Insert legal text here.")][assembly: AssemblyTrademark("More legal text")][assembly: AssemblyCulture(“en-US”)][assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyDelaySign(false)][assembly: AssemblyKeyFile("")][assembly: AssemblyKeyName("")]

Page 8: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Assembly Configuration Information Assembly Configuration Information

• use the application config file to upgrade one application and then use a publisher policy file to upgrade a component shared by many applications.– machine.config

<dependentAssembly> <assemblyIdentity name="MyAssembly" publicKeyToken="a0231341ddcfe32b" culture="neutral" /> <bindingRedirect oldVersion="1.0.1444.20531" newVersion="1.1.1455.20221" /></dependentAssembly>

Page 9: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Item 30: Prefer CLS-Compliant Assemblies

Page 10: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Common Language Subsystem (CLS)Common Language Subsystem (CLS)

• Fully interact with other objects regardless of the language .

• Define a set of basic language features needed by many applications.

Page 11: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

CLS-compliant assemblyCLS-compliant assembly

• Two rules to create a CLS-compliant assembly, – Rule1. the type of all parameters and return values from

public and protected members must be CLS compliant. – Rule2. any non-CLS-compliant public or protected member

must have a CLS-compliant synonym.

Page 12: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Rule1. CLS compliant memberRule1. CLS compliant member

• Add the CLSCompliant attribute to your assembly:– [ assembly: CLSCompliant( true ) ]

• Compiler enforces CLS compliance for the entire assembly

• CLS-compliant interfaces are required only for items that are exposed outside the assembly.– Compiler report an error if a public method or property that

is not compliant with CLS

Page 13: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample: incompliantSample: incompliant

// Not CLS Compliant, returns unsigned int:public UInt32 Foo( ){ return _foo;}

// Not CLS compliant, parameter is an unsigned int.public void Foo2( UInt32 parm ){}

Page 14: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample: PropertiesSample: Properties

// TheProperty is CLS compliant only if MyClass resides in a CLS-compliant assembly.public MyClass TheProperty{ get { return _myClassVar; } set { _myClassVar = value; }}

Page 15: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Rule2. CLS-compliant synonymRule2. CLS-compliant synonym

• The second rule is up to you: – make all public and protected operations are language-

agnostic. – make sure the polymorphism interface do not sneak a

noncompliant object.

Page 16: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Operator overloadingOperator overloading

• The CLS standard does not take a pro or con stance on the concept of operator overloading– not every language supports or allows operator

overloading.– it only defines a function name for each operator:

op_ function name Ex: op_equals, op_addis

Page 17: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample: overload an operatorSample: overload an operator

// Overloaded Addition operator, preferred C# syntax:public static Foo operator+( Foo left, Foo right){ // Use the same implementation as the Add method: return Foo.Add( left, right );}

// Static function, desirable for some languages:public static Foo Add( Foo left, Foo right){ return new Foo ( left.Bar + right.Bar );}

Page 18: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Non-CLS types sneaking into an interfaceNon-CLS types sneaking into an interface• Non-CLS types sneaking into an interface when you

use polymorphic arguments.– The end result is a type that some languages cannot use.

Page 19: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample: Hiding the non-compliant objectSample: Hiding the non-compliant object

// non-CLS types internal class BadEventArgs : EventArgs{ internal UInt32 ErrorCode;}

// Hiding the non-compliant event argument:public delegate void MyEventHandler(object sender, EventArgs args );

public event MyEventHandler OnStuffHappens;

// Code to raise Event:BadEventArgs arg = new BadEventArgs( );arg.ErrorCode = 24;

// Interface is legal, runtime type is not:OnStuffHappens( this, arg );

Page 20: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

CLS-compliant class implements Non -CLS compliant InterfaceCLS-compliant class implements Non -CLS compliant Interface• All interfaces that you implement publicly must be

CLS compliant.– Hide a non-CLS compliant interface from your public

interface using explicit interface implementation.

Page 21: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample: CLS-compliant class Sample: CLS-compliant class

public interface IFoo2{ // Non-CLS compliant, Unsigned int void DoStuff( UInt32 arg1, string arg2 );}

public class MyClass: IFoo2{ // explicit interface implementation. // DoStuff() is not part of MyClass's public interface void IFoo2.DoStuff( UInt32 arg1, string arg2 ) { // content elided. }}

Page 22: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

CLS compliantCLS compliant

• For any public or protected class, any type mentioned in these constructs must be CLS compliant:– Base classes– Return values for public and protected methods and

properties– Parameters for public and protected methods and indexers– Runtime event arguments– Public interfaces, declared or implemented

Page 23: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

SummarySummary

• CLS 相容之物件可跨程式語言執行 (.NET)• 物件開發者須提供 CLS 相容之物件使其他使用者可以簡

單的開發出 CLS 相容之程式• 創建 CLS 相容的程式集的兩個規則:

– Public 與 Protected 成員的 Parameter 與回傳質都必須是 CLS 相容。

– 非 CLS 相容的 Public 與 Protected 成員必須存在 CLS 相容的相容物件。

Page 24: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Item 31: Prefer Small, Simple Functions

Page 25: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

How the JIT compiler performs its workHow the JIT compiler performs its work

• Translate the IL (Intermediate Language, generated by C# compiler) into machine code

• The CLR invokes the JITer on a function-by-function basis– minimizes the startup cost to a reasonable level– minimize the amount of extraneous code– factoring code into more, smaller functions rather than

fewer larger functions

Page 26: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample: originalSample: original public string BuildMsg(bool takeFirstPath) { StringBuilder msg = new StringBuilder(); if (takeFirstPath) { msg.Append("A problem occurred."); msg.Append("\nThis is a problem."); msg.Append("imagine much more text"); } else { msg.Append("This path is not so bad."); msg.Append("\nIt is only a minor inconvenience."); msg.Append("Add more detailed diagnostics here."); } return msg.ToString(); }

Page 27: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample: optimizedSample: optimized

public string BuildMsg(bool takeFirstPath){ StringBuilder msg = new StringBuilder(); if (takeFirstPath) FirstPath(msg); else SecondPath(msg); return msg.ToString();}

private static void FirstPath(StringBuilder msg){ msg.Append("A problem occurred."); msg.Append("\nThis is a problem."); msg.Append("imagine much more text");}private static void SecondPath(StringBuilder msg){ msg.Append("This path is not so bad."); msg.Append("\nIt is only a minor inconvenience."); msg.Append("Add more detailed diagnostics here.");}

Page 28: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Enregistration Enregistration

• Smaller and simpler functions make it easier for the JIT compiler to support enregistration– Selecting which local variables can be stored in registers

rather than on the stack• For example:

– If a function has one loop, that loop variable will likely be enregistered.

– If a function with several loops, the JIT compiler must make some tough choices about enregistering loop variables.

Page 29: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

InliningInlining

• The JIT compiler also makes decisions about inlining methods– Substitute the body of a function for the function call– No keyword to give a hint to the compiler that a method

should be inlined.– The small functions that are virtual or that contain try/catch

blocks cannot be inlined

Page 30: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

Sample:Sample:

Original Optimized:

against with Item 1 public string _name;

// access:

string val = Obj._name;

// readonly name property:private string _name;public string Name{ get { return _name; }}

// access:string val = Obj.Name;

Page 31: Effective C# 50 Specific Way to Improve Your C# Item 30,31 Scott68.Chang.

SummarySummary

• C# Compiler 與 JIT Compiler 會自動針對硬體特性選擇最適合的方法來執行程式,而我們只須負責撰寫小而簡單的函數。