Tải bản đầy đủ (.ppt) (26 trang)

Tài liệu Introduction to CSharp 4.0 doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.57 MB, 26 trang )

C# 1.0
C# 2.0
C# 3.0
Managed Code
Generics
Language Integrated
Query
C# 4.0
Dynamic
Programming
C# 4.0 Language Innovations
Python
Python
Binder
Binder
Python
Python
Binder
Binder
Ruby
Ruby
Binder
Binder
Ruby
Ruby
Binder
Binder
COM
COM


Binder
Binder
COM
COM
Binder
Binder
JavaScript
JavaScript
Binder
Binder
JavaScript
JavaScript
Binder
Binder
Object
Object
Binder
Binder
Object
Object
Binder
Binder
Dynamic Language Runtime
Dynamic Language Runtime
Expression Trees
Expression Trees
Expression Trees
Expression Trees
Dynamic Dispatch
Dynamic Dispatch

Dynamic Dispatch
Dynamic Dispatch
Call Site Caching
Call Site Caching
Call Site Caching
Call Site Caching
IronPython
IronPython
IronPython
IronPython
IronRuby
IronRuby
IronRuby
IronRuby
C#
C#
C#
C#
VB.NET
VB.NET
VB.NET
VB.NET
Others…
Others…
Others…
Others…
.NET object
object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember("Add",

BindingFlags.InvokeMethod, null,
new object[] { 10, 20 });
int sum = Convert.ToInt32(res);
.NET object
object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember("Add",
BindingFlags.InvokeMethod, null,
new object[] { 10, 20 });
int sum = Convert.ToInt32(res);
Dynamic Language object
ScriptObject calc = GetCalculator();
object res = calc.Invoke("Add", 10, 20);
int sum = Convert.ToInt32(res);
Dynamic Language object
ScriptObject calc = GetCalculator();
object res = calc.Invoke("Add", 10, 20);
int sum = Convert.ToInt32(res);
Calculator calc = GetCalculator();
int sum = calc.Add(10, 20);
Calculator calc = GetCalculator();
int sum = calc.Add(10, 20);
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);
Statically typed
to be dynamic
Statically typed
to be dynamic

Dynamic
method
invocation
Dynamic
method
invocation
Dynamic
conversion
Dynamic
conversion
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);
dynamic i = 3;
Math.Abs(i);
dynamic i = 3;
Math.Abs(i);
Under the cover
dynamic d = new DynamicObject();
d.Foo();
dynamic d = new DynamicObject();
d.Foo();
public abstract class DynamicObject : IDynamicObject
{
public virtual object GetMember(GetMemberBinder info);
public virtual object SetMember(SetMemberBinder info, object value);
public virtual object DeleteMember(DeleteMemberBinder info);


public virtual object UnaryOperation(UnaryOperationBinder info);
public virtual object BinaryOperation(BinaryOperationBinder info, object arg);
public virtual object Convert(ConvertBinder info);

public virtual object Invoke(InvokeBinder info, object[] args);
public virtual object InvokeMember(InvokeMemberBinder info, object[] args);
public virtual object CreateInstance(CreateInstanceBinder info, object[] args);

public virtual object GetIndex(GetIndexBinder info, object[] indices);
public virtual object SetIndex(SetIndexBinder info, object[] indices, object value);
public virtual object DeleteIndex(DeleteIndexBinder info, object[] indices);

public MetaObject IDynamicObject.GetMetaObject();
}
public abstract class DynamicObject : IDynamicObject
{
public virtual object GetMember(GetMemberBinder info);
public virtual object SetMember(SetMemberBinder info, object value);
public virtual object DeleteMember(DeleteMemberBinder info);

public virtual object UnaryOperation(UnaryOperationBinder info);
public virtual object BinaryOperation(BinaryOperationBinder info, object arg);
public virtual object Convert(ConvertBinder info);

public virtual object Invoke(InvokeBinder info, object[] args);
public virtual object InvokeMember(InvokeMemberBinder info, object[] args);
public virtual object CreateInstance(CreateInstanceBinder info, object[] args);

public virtual object GetIndex(GetIndexBinder info, object[] indices);
public virtual object SetIndex(SetIndexBinder info, object[] indices, object value);

public virtual object DeleteIndex(DeleteIndexBinder info, object[] indices);

public MetaObject IDynamicObject.GetMetaObject();
}
Improved COM Interoperability
object -> dynamic mapping
((Excel.Range)xl.Cells[1,1]).Value2 = “ID”;
((Excel.Range)xl.Cells[1,1]).Value2 = “ID”;
We need to cast
We need to cast
xl.Cells[1,1].Value2 = “ID”;
Optional and named parameters
xlChart.ChartWizard(cellRange.CurrentRegion, Constants.xl3DBar,
PlotBy: Excel.XlRowCol.xlColumns,
SeriesLabels: 2,
CategoryLabels: 1,
HasLegend: false,
Title: xlSheet.Name);
Non-optional must
be specified
Non-optional must
be specified
Arguments
evaluated in order
written
Arguments
evaluated in order
written
Named arguments

can appear in any
order
Named arguments
can appear in any
order
xlChart.ChartWizard(cellRange.CurrentRegion,
Constants.xl3DBar, Type.Missing, Excel.XlRowCol.xlColumns,
1, 2, false, xlSheet.Name, Type.Missing,
Type.Missing, Type.Missing);
xlChart.ChartWizard(cellRange.CurrentRegion,
Constants.xl3DBar, Type.Missing, Excel.XlRowCol.xlColumns,
1, 2, false, xlSheet.Name, Type.Missing,
Type.Missing, Type.Missing);
public StreamReader OpenTextFile(
string path,
Encoding encoding,
bool detectEncoding,
int bufferSize);
public StreamReader OpenTextFile(
string path,
Encoding encoding,
bool detectEncoding,
int bufferSize);
public StreamReader OpenTextFile(
string path,
Encoding encoding = null,
bool detectEncoding = true,
int bufferSize = 1024);
public StreamReader OpenTextFile(
string path,

Encoding encoding = null,
bool detectEncoding = true,
int bufferSize = 1024);
Optional
parameters
Optional
parameters
OpenTextFile("foo.txt”);
OpenTextFile("foo.txt”);
OpenTextFile("foo.txt", Encoding.UTF8, bufferSize: 4096);
OpenTextFile("foo.txt", Encoding.UTF8, bufferSize: 4096);
Named argument
Named argument
Optional and named parameters
Optional “ref” modifier
object fileName = "Test.docx";
object missing = System.Reflection.Missing.Value;
doc.SaveAs(ref fileName,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing);
object fileName = "Test.docx";
object missing = System.Reflection.Missing.Value;
doc.SaveAs(ref fileName,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,

ref missing, ref missing, ref missing);
doc.SaveAs("Test.docx");
Under the cover
Under the cover
void Process(object[] objects) { … }
void Process(object[] objects) { … }
string[] strings = GetStringArray();
Process(strings);
string[] strings = GetStringArray();
Process(strings);
void Process(object[] objects) {
objects[0] = "Hello"; // Ok
objects[1] = new Button(); // Exception!
}
void Process(object[] objects) {
objects[0] = "Hello"; // Ok
objects[1] = new Button(); // Exception!
}
List<string> strings = GetStringList();
Process(strings);
List<string> strings = GetStringList();
Process(strings);
void Process(IEnumerable<object> objects) { … }
void Process(IEnumerable<object> objects) { … }
.NET arrays are
co-variant
.NET arrays are
co-variant
…but not safely
co-variant

…but not safely
co-variant
Until now, C#
generics have
been invariant
Until now, C#
generics have
been invariant
void Process(IEnumerable<object> objects) {
// IEnumerable<T> is read-only and
// therefore safely co-variant
}
void Process(IEnumerable<object> objects) {
// IEnumerable<T> is read-only and
// therefore safely co-variant
}
C# 4.0 supports
safe co- and
contra-variance
C# 4.0 supports
safe co- and
contra-variance
public interface IEnumerable<T>
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerable<T>
{
IEnumerator<T> GetEnumerator();
}

public interface IEnumerator<T>
{
T Current { get; }
bool MoveNext();
}
public interface IEnumerator<T>
{
T Current { get; }
bool MoveNext();
}
public interface IEnumerable<out T>
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerable<out T>
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T>
{
T Current { get; }
bool MoveNext();
}
public interface IEnumerator<out T>
{
T Current { get; }
bool MoveNext();
}
out = Co-variant
Output positions only

out = Co-variant
Output positions only
IEnumerable<string> strings = GetStrings();
IEnumerable<object> objects = strings;
IEnumerable<string> strings = GetStrings();
IEnumerable<object> objects = strings;
Can be treated as
less derived
Can be treated as
less derived
public interface IComparer<T>
{
int Compare(T x, T y);
}
public interface IComparer<T>
{
int Compare(T x, T y);
}
public interface IComparer<in T>
{
int Compare(T x, T y);
}
public interface IComparer<in T>
{
int Compare(T x, T y);
}
IComparer<object> objComp = GetComparer();
IComparer<string> strComp = objComp;
IComparer<object> objComp = GetComparer();
IComparer<string> strComp = objComp;

in = Contra-
variant
Input positions
only
in = Contra-
variant
Input positions
only
Can be treated as
more derived
Can be treated as
more derived
Variance in C# 4.0
class Base {
public virtual void Foo(int x = 4, int y = 5) {
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}
class Derived : Base {
public override void Foo(int y = 4, int x = 5) {
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}
class Program {
static void Main(string[] args) {
Base b = new Derived();
b.Foo(x: 4, y: 5);
}

}
class Base {
public virtual void Foo(int x = 4, int y = 5) {
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}
class Derived : Base {
public override void Foo(int y = 4, int x = 5) {
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}
class Program {
static void Main(string[] args) {
Base b = new Derived();
b.Foo(x: 4, y: 5);
}
}
Output:
a)x:4, y:5
b)x:5, y:4
c)x:4, y:4
d)x:5, y:5
e)None of the above
Output:
a)x:4, y:5
b)x:5, y:4
c)x:4, y:4
d)x:5, y:5
e)None of the above
Output:

a)x:4, y:5
b)x:5, y:4
c)x:4, y:4
d)x:5, y:5
e)None of the above
Output:
a)x:4, y:5
b)x:5, y:4
c)x:4, y:4
d)x:5, y:5
e)None of the above

×