Internationalizing WPF And Silverlight Applications · 2009. 5. 4. · Title: Internationalizing...

Preview:

Citation preview

1Guy Smith-Ferrier

What's New In C# 4 ?

Guy Smith-Ferrierguy@guysmithferrier.com

Blog: http://www.guysmithferrier.com

2Guy Smith-Ferrier

About…

Author of .NET Internationalization

– Visit http://www.dotneti18n.com to

download the complete source code

The .NET Developer Network

– http://www.dotnetdevnet.com

– Free user group for .NET developers,

architects and IT Pros based in Bristol

DDD South West

– http://www.dddsouthwest.com

– Taunton, Saturday 23rd May 2009

3Guy Smith-Ferrier

Agenda

Dynamically Typed Objects

Optional And Named Parameters

Improvements To COM Support

Co- and contra-variance

Beyond C# 4

4Guy Smith-Ferrier

Dynamic Type

dynamic myInt = 1;

myInt = "Hello World";

CultureInfo cultureInfo;

dynamic myVar = 1033;

cultureInfo = CultureInfo.GetCultureInfo(myVar);

myVar = "en-US";

cultureInfo = CultureInfo.GetCultureInfo(myVar);

System.Console.WriteLine(cultureInfo.Name);

object myInt = 1;

myInt = "Hello World";

5Guy Smith-Ferrier

Consuming JavaScript Dynamic

Types From Silverlight (1 of 4)<html>

<head>

<title>SilverlightApplication1</title>

<script type="text/javascript">

var map;

function CreateMap() {

map = new VEMap("myMap");

map.LoadMap();

}

function UpdateMap(latitude, longitude) {

map.DeleteAllShapes();

var x = new VELatLong(latitude, longitude);

var pin = map.AddPushPin(x);

map.SetCenterAndZoom(x, 9);

}

</script>

6Guy Smith-Ferrier

Consuming JavaScript Dynamic

Types From Silverlight (2 of 4)

public partial class Page1 : Page

{

HtmlWindow htmlWindow = HtmlPage.Window;

public void Init()

{

htmlWindow.Invoke("CreateMap");

}

void Customers_SelectionChanged(

object sender, SelectionChangedEventArgs args)

{

Customer customer = customers.SelectedItem as Customer;

HtmlDocument htmlDocument = HtmlPage.Document;

htmlDocument.SetProperty("Title", customer.Name);

htmlWindow.Invoke("UpdateMap",

customer.Latitude, customer.Longitude);

}

}

7Guy Smith-Ferrier

Consuming JavaScript Dynamic

Types From Silverlight (3 of 4)

public partial class Page1 : Page

{

dynamic htmlWindow = HtmlPage.Window.AsDynamic();

public void Init()

{

htmlWindow.CreateMap();

}

void Customers_SelectionChanged(

object sender, SelectionChangedEventArgs args)

{

Customer customer = customers.SelectedItem as Customer;

dynamic htmlDocument = HtmlPage.Document.AsDynamic();

htmlDocument.Title = customer.Name;

htmlWindow.UpdateMap(customer.Latitude, customer.Longitude);

}

}

8Guy Smith-Ferrier

Consuming JavaScript Dynamic

Types From Silverlight (4 of 4)

dynamic map;

function void CreateMap() {

map = win.New.VEMap("myMap");

map.LoadMap();

}

function void UpdateMap(dynamic latitude, dynamic longitude) {

map.DeleteAllShapes();

dynamic x = win.New.VELatLong(latitude, longitude);

dynamic pin = map.AddPushPin(x);

map.SetCenterAndZoom(x, 9);

}

This syntax is

temporary

9Guy Smith-Ferrier

Support For Dynamic Languages

In The .NET Framework 4.0

Dynamic Language Runtime

Expression Trees Dynamic Dispatch Call Site Caching

IronPython IronRuby C# VB.NET Others

Python Ruby .NET OfficeSilverlight

Python

Binder

Ruby

Binder

Object

Binder

Java

Script

Binder

COM

Binder

10Guy Smith-Ferrier

Implementing IDynamicObject

The Goalstatic void Main(string[] args)

{

dynamic resource =

new DynamicallyTypedResXResource("Resource1.resx");

Console.WriteLine(resource.HelloWorld);

}

static void Main(string[] args)

{

dynamic resource =

new DynamicallyTypedDbResource("Resource1");

Console.WriteLine(resource.HelloWorld);

}

11Guy Smith-Ferrier

Implementing IDynamicObject

The Solutionpublic class DynamicallyTypedResXResource: DynamicObject

{

Dictionary<string, object> dictionary = new Dictionary<string, object>();

public DynamicallyTypedResXResource(string resxFilename)

{

ResXResourceReader reader = new ResXResourceReader(resxFilename);

IEnumerator enumerator = reader.GetEnumerator();

while (enumerator.MoveNext())

{

DictionaryEntry entry = (DictionaryEntry) enumerator.Current;

dictionary.Add(entry.Key.ToString(), entry.Value);

}

}

public override object GetMember(GetMemberAction action)

{

return dictionary[action.Name];

}

}

"HelloWorld"

12Guy Smith-Ferrier

DynamicObject Methods

public class DynamicObject : IDynamicObject

{

public virtual object GetMember(GetMemberAction action);

public virtual void SetMember(SetMemberAction action, object value);

public virtual bool DeleteMember(DeleteMemberAction action);

public virtual object Call(CallAction action, params object[] args);

public virtual object Convert(ConvertAction action);

public virtual object Create(CreateAction action, params object[] args);

public virtual object Invoke(InvokeAction action, params object[] args);

public virtual object Operation(OperationAction action, params object[] args);

}

13Guy Smith-Ferrier

Benefits Of Dynamic Typing

Program against dynamically typed languages

using the same syntax as for static languages

– e.g. JavaScript from Silverlight

– Write code in .NET that traditionally has been

written in other languages (e.g. JavaScript)

Program against dynamic structures using the

same syntax as for static structures

– e.g. XML, DataSets

14Guy Smith-Ferrier

Optional Parameters (1 of 2)

static void JoinUserGroup(string userGroupName, bool isFree, bool hasGreatSpeakers, bool hasSwag)

{

}

static void JoinUserGroup(string userGroupName, bool isFree, bool hasGreatSpeakers)

{

}

static void JoinUserGroup(string userGroupName, bool isFree)

{

}

static void JoinUserGroup(string userGroupName)

{

}

15Guy Smith-Ferrier

Optional Parameters (2 of 2)static void JoinUserGroup(

string userGroupName,

bool isFree = true,

bool hasGreatSpeakers = true,

bool hasSwag = true)

{

}

static void Main(string[] args)

{

JoinUserGroup("DotNetDevNet", true, true, true);

JoinUserGroup("DotNetDevNet", true, true);

JoinUserGroup("DotNetDevNet", true);

JoinUserGroup("DotNetDevNet");

}

16Guy Smith-Ferrier

Named Parametersstatic void Main(string[] args)

{

JoinUserGroup("NxtGen", isFree: false);

JoinUserGroup("DotNetDevNet",

hasSwag: true, isFree: true, hasGreatSpeakers: true);

}

17Guy Smith-Ferrier

Improved COM Support

Dynamic Type

Optional and named parameters

Support for COM indexed properties

ref modifier is now optional

Type Equivalence and Type Embedding (NoPIA)

Improvements in COM event handling

18Guy Smith-Ferrier

Dynamic Types And COM

When you import a type library in .NET 4

you can choose whether to import types as

object (.NET 1 to 3.5) or dynamic (.NET 4)

// C# 1 to 3.5

((Excel.Range)excel.Cells[1, 1]).Value2 = "Hello";

Excel.Range range = (Excel.Range)excel.Cells[1, 1];

// C# 4 (type library imported with dynamic types)

excel.Cells[1, 1].Value = "Hello";

Excel.Range range = excel.Cells[1, 1];

19Guy Smith-Ferrier

Optional and Named

Parameters And COM// C# 1 to 3.5

Excel.Chart chart = (Excel.Chart)

excel.Application.Charts.Add(Type.Missing, excel.ActiveSheet, Type.Missing, Type.Missing);

// C# 4

Excel.Chart chart =

excel.Application.Charts.Add(After: excel.ActiveSheet);

20Guy Smith-Ferrier

ref Modifier Is Optional

// C# 1 to 3.5

var missing = Type.Missing;

word.Documents.Add(ref missing, ref missing, ref missing,

ref missing);

// C# 4

word.Documents.Add();

21Guy Smith-Ferrier

Type Embedding (1 of 4)

Types from COM type

libraries can be

optionally embedded in

the assembly

The default will be

True for new projects

22Guy Smith-Ferrier

Type Embedding (2 of 4) No Primary Interop Assembly (PIA) is required

Partial 'local' versions of the types are copied

into the assembly

Primary

Interop

Assembly

Visual Studio

(Intellisense)

C# Compiler

Assembly

Local Types

23Guy Smith-Ferrier

Type Embedding (3 of 4)

Only the methods used

by the application are

included in the

interface

– all other methods are

represented by 'vtable

gaps'

24Guy Smith-Ferrier

Type Embedding (4 of 4)

Only types from interop assemblies can be

embedded

– Assemblies must have the following attributes:-

Only metadata is embedded

– interfaces, delegates, enums, simple structs

– Classes cannot be embedded

[assembly:Guid()]

[assembly:ImportedFromTypeLib()]

25Guy Smith-Ferrier

Type Equivalence

Interfaces that have the same GUID are

treated as equivalent types by the CLR

– At least one of the interfaces must have a

TypeIdentifier attribute

– .NET languages (C#, Visual Basic.NET etc.)

require the namespace to be the same

Structs also support type equivalence

– Full Trust is required

– Full Trust may be required for interfaces in a

future CTP

26Guy Smith-Ferrier

Benefits Of Type Embedding

And Type Equivalence (NoPIA)

Smaller deployment footprint

– Office 2007 PIA footprint is 6.3Mb

Lower memory requirement

Develop against one version of Office (e.g.

2003) and run against a different version

(e.g. 2007)

27Guy Smith-Ferrier

COM Event Handling (1 of 2)

The compiler now recognises subscription

to COM events and generates different code

The new code does not suffer from "ghost

RCWs" (Runtime Callable Wrapper)

Excel.Application excelApplication = new Excel.Application();

excelApplication.SheetSelectionChange += SheetSelectionChange;

28Guy Smith-Ferrier

COM Event Handling (2 of 2)ComEventsHelper.Combine(excelApplication,

new Guid("00024413-0000-0000-C000-000000000046"),

0x616,

new AppEvents_SheetSelectionChangeEventHandler(

WindowsApplication1.SheetSelectionChange));

[Guid("00024413-0000-0000-C000-000000000046")]

public interface AppEvents

{

[DispId(2612)]

void AfterCalculate();

[DispId(1558)]

void SheetSelectionChange(object Sh, Range Target);

[DispId(1556)]

void WindowActivate(Workbook Wb, Window Wn);

29Guy Smith-Ferrier

Co-Variance And Contra-Variance// C# 1, 2, 3, 3.5 and 4

IList<string> strings = new List<string>();

// Cannot implicitly convert type

IList<object> objects = strings;

// this is illegal because objects[0] is strings[0]

objects[0] = 42;

IList<string> strings = new List<string>();

// this will work in a future version of C# 4

IEnumerable<object> objects = strings;

30Guy Smith-Ferrier

Co-Variance (out modifier)

public interface IEnumerable<out T>: IEnumerable

{

IEnumerator<T> GetEnumerator();

}

31Guy Smith-Ferrier

Contra-Variance (in modifier)

public interface IComparer<in T>: IEnumerable

{

public int Compare(T left, T right);

}

32Guy Smith-Ferrier

Variance Limitations

Variance type parameters can only be

declared on interfaces and delegates

Variance only applies when there is a

reference conversion

– IEnumerable<int> to IEnumerable<object> is a

boxing conversion not a reference conversion

33Guy Smith-Ferrier

Beyond C# 4

Compiler As A Service (1 of 4)

public class CSharpEvaluator

{

public CSharpEvaluator();

public CSharpEvaluator(CSharpCompiler compiler);

public Collection<assembly> References { get; }

public Collection<string> Usings { get; }

public void Clear();

public EvaluationResult Eval(string program);

public bool IsComplete(string program);

}

34Guy Smith-Ferrier

Beyond C# 4

Compiler As A Service (2 of 4)

public class EvaluationResult

{

public EvaluationResult(

object value, IList<ICSError> errors);

public IList<ICSErrors> Errors { get; }

public object Value { get; }

public override string ToString();

}

35Guy Smith-Ferrier

Beyond C# 4

Compiler As A Service (3 of 4)

static void Main(string[] args)

{

CSharpEvaluator evaluator = new CSharpEvaluator();

evaluator.Usings.Add("System");

EvaluationResult result = evaluator.Eval("1 + 2");

Console.WriteLine(result);

}

36Guy Smith-Ferrier

Beyond C# 4

Compiler As A Service (4 of 4)public class CSharpCompiler

{

public CSharpCompiler();

public BoundAssembly Bind(...);

public CompileResult Compile(...);

public CompileResult CompileTextIntoAssembly(...);

public CompileResult CompileTextToAssembly(...);

public CompileResult CompileToAssembly(...);

public void Emit(...);

public void EmitIntoAssembly(...);

public Assembly EmitToAssembly(...);

public SyntaxDocument Parse(...);

}

37Guy Smith-Ferrier

Uses For "Compiler As A

Service"

Read-Eval-Print Loop (REPL)

C# scripting (runtime extensibility)

– Embed C# in Domain Specific Languages

e.g. Windows Workflow code snippets

Meta programming

Language Object Model

– To enable C# refactoring

38Guy Smith-Ferrier

Summary

Dynamically Typed Objects

Optional And Named Parameters

Improvements To COM Support

Co- and contra-variance

Beyond C# 4

Recommended