Top Banner
C# 6.0 Preview 小小 小小小 2014-08-30
66

C# 6.0 Preview

Nov 12, 2014

Download

Technology

Fujio Kojima

『Hokuriku.NET vol.15』
http://hokurikunet.doorkeeper.jp/events/13746
2014-08-30(土)
「酒の肴はC# vNext」の資料
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: C# 6.0 Preview

C# 6.0 Preview

小島 富治雄2014-08-30

Page 2: C# 6.0 Preview

自己紹介

• 小島 富治雄

• @Fujiwo• 福井コンピュータアーキテクト株式会社

• Microsoft MVP C# (2005-2015)• プログラミング C# - 翔ソフトウェア

(Sho's)• http://blog.shos.info

Page 3: C# 6.0 Preview

•スライドhttp://1drv.ms/1vcTMOp•サンプル コード

http://1drv.ms/1vcTNSv

本日の資料

Page 4: C# 6.0 Preview

1. C# 6.0 とは2. C# 6.0 Demo3. C# 6.0 考察

アジェンダ

Page 5: C# 6.0 Preview

C#6.0 とは

Page 6: C# 6.0 Preview

C# の進化

6

C# 1.0 C# 2.0C# 3.0C# 4.0C# 5.0C# 6.0

オブジェクト指向ジェネリック

関数型dynamic

非同期Roslyn

Page 7: C# 6.0 Preview

7

C# におけるパラダイムの追加の歴史

delegate

C# 1.X C# 2.0 C# 3.0 C# 4.0 C# 5.0

class

手続き型 関数型

ラムダ式

LINQ

型推論

ジェネリック

拡張メソッド

動的型付け

dynamic

非同期

async/await

オブジェクト指向

Parallel

メタプログラミング

Roslyn

C# 6.0

Page 8: C# 6.0 Preview

.NET Compiler Platform ("Roslyn")

•次世代の C# (VB) コンパイラー• オープンソース

•コード分析 ( 等の ) API 

Page 9: C# 6.0 Preview

.NET Compiler Platform (“Roslyn”)での C# 6.0 の現状

• .NET Compiler Platform ("Roslyn")• http://roslyn.codeplex.com

Page 10: C# 6.0 Preview
Page 11: C# 6.0 Preview

• ++C++; // 未確認飛行 C ブログ• .NET Compiler Platform (Roslyn) Preview |

++C++; // 未確認飛行 C ブログ• https://ufcpp.wordpress.com/2014/04/04/net-

compiler-platform-roslyn-preview/• C# before/after• https://ufcpp.wordpress.com/2014/04/06/c-be

foreafter/

C# 6.0 の紹介記事 ( 日本語 )

Page 12: C# 6.0 Preview

• Try! C# vNext - xin9le.net• http://xin9le.net/csharp-vnext

C# 6.0 の紹介記事 ( 日本語 )

Page 13: C# 6.0 Preview

• C# 6.0 言語プレビュー - MSDN マガジン May 2014• http://msdn.microsoft.com/ja-jp/magazine

/dn683793.aspx

C# 6.0 の紹介記事 ( 日本語 )

C# vNext ( 以下 C# 6.0 。ただし、非公式名称なので注意してください ) をすぐに使用する予定がなくても、その機能を知れば、今すぐ導入する価値があると考えるでしょう。

Page 14: C# 6.0 Preview

• Briefly exploring C# 6 new features - CodeProject• http://www.codeproject.com/Articles/8087

32/Briefly-exploring-Csharp-new-features

C# 6.0 の紹介記事 ( 英語 )

Page 16: C# 6.0 Preview

Language Feature Status• Exists: Already shipped in previous release• Done: Implemented for this release• Planned: Intended for this release• Maybe: Possibly intended for this release• Withdrawn: Probably not in this release• No: Not intended for this release• N/A: Not meaningful for this language• http://

roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status

Page 17: C# 6.0 Preview

Feature Example C# VB Primary constructors class Point(int x, int y) { … } Done Maybe

Auto-property initializers public int X { get; set; } = x; Done Exists

Getter-only auto-properties public int Y { get; } = y; Done Done

Using static members

using System.Console; … Write(4); Done Exists

Dictionary initializer

new JObject { ["x"] = 3, ["y"] = 7 } Done Planned

Indexed member initializer

new JObject { $x = 3, $y = 7 } Withdrawn Planned

Indexed member access

c.$name = c.$first + " " + c.$last; Withdrawn Exists

Declaration expressions int.TryParse(s, out var x); Done Maybe

Await in catch/finally

try … catch { await … } finally { await … } Done Planned

Exception filters catch(E e) if (e.Count > 5) { … } Done Exists

Typecase Select Case o : Case s As String : … No Maybe

Guarded cases Select Case i : Case Is > 0 When i Mod 2 = 0 No Maybe

Partial modules Partial Module M1 N/A Done

Partial interfaces Partial Interface I1 Exists Done

Multiline string literals "Hello<newline>World" Exists Done

Year-first date literals Dim d = #2014-04-03# N/A Done

Binary literals 0b00000100 Planned Planned Digit separators 0xEF_FF_00_A0 Planned Planned

Feature Example C# VB Line continuation comments

Dim addrs = From c in Customers ' comment N/A Done

TypeOf IsNot If TypeOf x IsNot Customer Then … N/A Done

Expression-bodied members

public double Dist => Sqrt(X * X + Y * Y); Planned No

Event initializers

new Customer { Notify += MyHandler }; Planned Planned

Null propagation customer?.Orders?[5]?.$price Done Planned Semicolon operator

(var x = Foo(); Write(x); x * x) Maybe Maybe

Private protected

private protected string GetId() { … } Withdrawn Withdrawn

Params IEnumerable

int Avg(params IEnumerable<int> numbers) { … }

Planned Planned

Constructor Inference new Tuple(3, "three", true); Maybe Maybe

String interpolation

"\{p.First} \{p.Last} is \{p.Age} years old." Maybe Maybe

TryCast for nullable Dim x = TryCast(u, Integer?) Exists Planned

Delegate combination with +

d1 += d2 Exists Planned

Implicit implementation

Class C : Implicitly Implements I Exists Planned

nameof operator string s = nameof(Console.Write); Exists Planned

Strict modules Strict Module M Exists Planned

Faster CInt Dim x = CInt(Math.Truncate(d)) | Exists Planned

#pragma #Disable Warning BC40008 Exists Planned

Checked and Unchecked blocks Checked : x += 1 : End Checked Exists Maybe

Field targets on autoprops

<Field: Serializable> Property p As Integer Planned Planned

Last edited Tue at 8:23 AM by madst, version 28

Page 18: C# 6.0 Preview

• Visual Studio “14” CTP 3 Released• http://

blogs.msdn.com/b/visualstudio/archive/2014/08/18/visual-studio-14-ctp-3-released.aspx

Visual Studio “14” CTP 3 ( 最新 )

Page 19: C# 6.0 Preview

•~ .csproj ファイル に 1 行を追加

C#6.0 を試すとき

<?xml version="1.0" encoding="utf-8"?><Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />  <PropertyGroup>     ……    <LangVersion>experimental</LangVersion>  </PropertyGroup>     ……</Project>

Page 20: C# 6.0 Preview

C# 6.0 Demo

Page 21: C# 6.0 Preview

静的メンバーへの簡易アクセス (Using static)using System.Console; // 静的メンバーへの簡易アクセス (Using static)

using System.Math; // 静的メンバーへの簡易アクセス (Using static)

using System.Linq.Enumerable; // 静的メンバーへの簡易アクセス (Using static)

class Program

{

static void Main()

{

// 静的メンバーへの簡易アクセス (Using static)

WriteLine("Hello world!");

var root2 = Sqrt(2.0);

// 静的メンバーへの簡易アクセス : 拡張メソッド

var data = new[] { 2, 4, -1, 3, 0 };

var odd = Where(data, number => number % 2 != 0); // Ok

//var even = data.Where(i => i % 2 == 0); // Error, using System.Linq が無いのでスコープ外

}

}

Page 22: C# 6.0 Preview

参考 : beforeusing System;

using System.Linq;

class Program

{

static void Main()

{

Console.WriteLine("Hello world!");

var root2 = Math.Sqrt(2.0);

// 静的メンバーへの簡易アクセス : 拡張メソッド

var data = new[] { 2, 4, -1, 3, 0 };

var odd = Enumerable.Where(data, number => number % 2 != 0);

var even = data.Where(i => i % 2 == 0);

}

}

Page 23: C# 6.0 Preview

プライマリ コンストラクタusing System;

// プライマリ コンストラクタ (Primary constructors)

class Employee(int number, string name) // Parameters on classes

{

{ // プライマリ コンストラクタ本体

if (number < 0 || string.IsNullOrWhiteSpace(name))

throw new ArgumentOutOfRangeException();

}

// Explicit constructors

public Employee(string name)

: this(1, name) // プライマリ コンストラクタを呼ぶ

{ }

// Getter のみの自動実装プロパティ (Getter-only auto-properties)

// 自動実装プロパティ初期化子 (Initializers for auto-properties)

public double Number { get; } = number;

public string Name { get; } = name ;

}

class Staff(int number, string name, DateTime hiredDate)

: Employee(number, name) // ベース クラスのコンストラクタを呼ぶ

{

DateTime hiredDate_ = hiredDate; // 初期化のスコープ

//void TemporaryFunction()

//{

// var hiredDate_ = hiredDate; // NG

//}

}

class Program

{

static void Main()

{

var employee = new Employee(1, " 山田太郎 ");

var staff = new Staff (1, " 福井太郎 ", DateTime.Now);

}

}

Page 24: C# 6.0 Preview

参考 : beforeusing System;

class Employee

{

public Employee(int number, string name)

{

if (number < 0 || string.IsNullOrWhiteSpace(name))

throw new ArgumentOutOfRangeException();

Number = number;

Name = name ;

}

public Employee(string name)

: this(1, name)

{ }

public int Number { get; private set; }

public string Name { get; private set; }

}

class Staff : Employee

{

DateTime hiredDate_;

public Staff(int number, string name, DateTime hiredDate)

: base(number, name) // ベース クラスのコンストラクタを呼ぶ

{

this.hiredDate_ = hiredDate;

}

}

class Program

{

static void Main()

{

var employee = new Employee(1, " 山田太郎 ");

var staff = new Staff (1, " 福井太郎 ", DateTime.Now);

}

}

Page 25: C# 6.0 Preview

Expression-bodied membersusing System.Console; // 静的メンバーへの簡易アクセス (Using static)

using System.Math; // 静的メンバーへの簡易アクセス (Using static)

class Program

{

static void Main()

{

var point1 = new Point();

var point2 = new Point(1.1, 2.2);

(point1 + point2).Print();

}

}

class Point(double x = 0.0, double y = 0.0) // プライマリ コンストラクタ (Primary constructors)

{

public double X { get; } = x; // Getter のみの自動実装プロパティ (Getter-only auto-properties)/ 自動実装プロパティ初期化子 (Initializers for auto-properties)

public double Y { get; } = y; // Getter のみの自動実装プロパティ (Getter-only auto-properties)/ 自動実装プロパティ初期化子 (Initializers for auto-properties)

// Expression bodies on property-like function members

public double Length => Sqrt(X * X + Y * Y); // 静的メンバーへの簡易アクセス (Using static)

// Expression bodies on method-like members

public static Point operator +(Point point1, Point point2)

=> new Point(point1.X + point2.X, point1.Y + point2.Y);

// Expression bodies on method-like members (void)

public void Print() => WriteLine("({0}, {1})", X, Y); // 静的メンバーへの簡易アクセス (Using static)

// Expression bodied indexers

// public double this[int index] => index == 0 ? X : Y; // not yet

}

Page 26: C# 6.0 Preview

参考 : beforeusing System;

class Program

{

static void Main()

{

var point1 = new Point(-0.1, 3.8);

var point2 = new Point(1.1, 2.2);

(point1 + point2).Print();

}

}

class Point

{

public Point(double x = 0.0, double y = 0.0)

{

X = x;

Y = y;

}

public double X { get; private set; }

public double Y { get; private set; }

public double Length

{

get { return Math.Sqrt(X * X + Y * Y); }

}

public static Point operator +(Point point1, Point point2)

{ return new Point(point1.X + point2.X, point1.Y + point2.Y); }

public void Print()

{ Console.WriteLine("({0}, {1})", X, Y); }

public double this[int index]

{

get { return index == 0 ? X : Y; }

}

}

Page 27: C# 6.0 Preview

struct の場合using System.Console; // 静的メンバーへの簡易アクセス (Using static)

// プライマリ コンストラクタ (Primary constructors)

public struct Tally(int count, int sum) // Parameters on structs

{

// Getter のみの自動実装プロパティ (Getter-only auto-properties)

// 自動実装プロパティ初期化子 (Initializers for auto-properties)

public int Count { get; } = count;

public int Sum { get; } = sum ;

// Expression bodies on property-like function members

public double Average => (double)Sum / Count;

}

class Program

{

static void Main()

{

var tally = new Tally(10, 500);

WriteLine(tally.Average); // 静的メンバーへの簡易アクセス (Using static)

}

}

Page 28: C# 6.0 Preview

参考 : beforeusing System;

public struct Tally

{

int count;

int sum ;

public int Count { get { return count; } }

public int Sum { get { return sum ; } }

public Tally(int count, int sum)

{

this.count = count;

this.sum = sum ;

}

public double Average

{

get { return (double)Sum / Count; }

}

}

class Program

{

static void Main()

{

var tally = new Tally(10, 500);

Console.WriteLine(tally.Average);

}

}

Page 29: C# 6.0 Preview

変数宣言式 (Declaration expressions)using System.Console; // 静的メンバーへの簡易アクセス (Using static)

using System.Linq;

class Program

{

static void Sub(object item)

{

if ((var text = item as string) != null)

WriteLine(text); // 静的メンバーへの簡易アクセス (Using static)

}

static void Main()

{

// 変数宣言式 (Declaration expressions)

if (int.TryParse("123", out int number))

WriteLine(number); // 静的メンバーへの簡易アクセス (Using static)

var texts = new[] { "123", "a123", "-34", "Q", "123" };

var sum1 = texts.Select(text => int.TryParse(text, out int number) ? number : 0).Sum();

WriteLine(sum1); // 静的メンバーへの簡易アクセス (Using static)

var sum2 = texts.Select(text => int.TryParse(text, out var number) ? number : 0).Sum();

WriteLine(sum2); // 静的メンバーへの簡易アクセス (Using static)

Sub("ABC");

}

}

Page 30: C# 6.0 Preview

参考 : beforeusing System.Console; // 静的メンバーへの簡易アクセス (Using static)

using System.Linq;

class Program

{

static void Sub(object item)

{

if ((var text = item as string) != null)

WriteLine(text); // 静的メンバーへの簡易アクセス (Using static)

}

static void Main()

{

// 変数宣言式 (Declaration expressions)

if (int.TryParse("123", out int number))

WriteLine(number); // 静的メンバーへの簡易アクセス (Using static)

var texts = new[] { "123", "a123", "-34", "Q", "123" };

var sum1 = texts.Select(text => int.TryParse(text, out int number) ? number : 0).Sum();

WriteLine(sum1); // 静的メンバーへの簡易アクセス (Using static)

var sum2 = texts.Select(text => int.TryParse(text, out var number) ? number : 0).Sum();

WriteLine(sum2); // 静的メンバーへの簡易アクセス (Using static)

Sub("ABC");

}

}

Page 31: C# 6.0 Preview

null 伝搬演算子 (Null-conditional operators)using System.Console; // 静的メンバーへの簡易アクセス (Using static)

class Person

{

public string Name { get; set; }

}

class Program

{

static void Main()

{

// null 伝搬演算子 (Null-conditional operators)

Person person = null;

var name1 = person?.Name?.Trim() ?? "anonymous";

WriteLine(name1); // 静的メンバーへの簡易アクセス (Using static)

Person[] people = null;

var name2 = people?[0]?.Name?.Trim() ?? "anonymous";

WriteLine(name2); // 静的メンバーへの簡易アクセス (Using static)

}

}

Page 32: C# 6.0 Preview

参考 : beforeusing System;

class Person

{

public string Name { get; set; }

}

class Program

{

static void Main()

{

Person person1 = null;

if (person1 != null) {

var name = person1.Name;

if (name != null) {

name = name.Trim();

Console.WriteLine(name);

}

}

Person[] people = null;

if (people != null) {

var person2 = people[0];

if (person2 != null) {

var name = person2.Name;

if (name != null) {

name = name.Trim();

Console.WriteLine(name);

}

}

}

}

}

Page 33: C# 6.0 Preview

catch/finally での await (Await in catch/finally)using System;

using System.Console; // 静的メンバーへの簡易アクセス (Using static)

using System.Threading.Tasks;

// catch/finally での await (Await in catch/finally)

class Program

{

static async Task DoSomethingCanFailAsync()

{

await Task.Delay(1000);

if (true)

throw new Exception("Error!");

}

static async Task ErrorFunctionAsync(string errorMessage)

{

await Task.Delay(1000);

WriteLine(errorMessage); // 静的メンバーへの簡易アクセス (Using static)

}

static async Task Sub()

{

try {

await DoSomethingCanFailAsync();

} catch (Exception ex) {

await ErrorFunctionAsync(ex.Message);

}

}

static void Main()

{

Sub().Wait();

}

}

Page 34: C# 6.0 Preview

参考 : beforeusing System;

using System.Threading.Tasks;

class Program

{

static async Task DoSomethingCanFailAsync()

{

await Task.Delay(1000);

if (true)

throw new Exception("Error!");

}

static async Task ErrorFunctionAsync(string errorMessage)

{

await Task.Delay(1000);

Console.WriteLine(errorMessage);

}

{

Exception exception = null;

try {

await DoSomethingCanFailAsync();

} catch (Exception ex) {

exception = ex;

}

if (exception != null)

await ErrorFunctionAsync(exception.Message);

}

static void Main()

{

Sub().Wait();

}

}

Page 35: C# 6.0 Preview

例外フィルター (Exception filters)using System;

using System.Console; // 静的メンバーへの簡易アクセス (Using static)

// プライマリ コンストラクタ (Primary constructors)

class MyException(MyException.Type state = MyException.Type.Normal)

: Exception

{

public enum Type

{ Normal, Abnormal }

public Type State { get; } = state; // Getterのみの自動実装プロパティ (Getter-only auto-properties)/ 自動実装プロパティ初期化子 (Initializers for auto-properties)

}

class Program

{

static void Sub()

{

throw new MyException(MyException.Type.Abnormal);

}

static void Main()

{

// 例外フィルター (Exception filters)

try {

Sub();

} catch (MyException ex) if (ex.State == MyException.Type.Abnormal) { // 例外フィルター (Exception filters)

WriteLine("catch block: Abnormal."); // 静的メンバーへの簡易アクセス (Using static)

} catch (MyException ex) {

WriteLine("catch block: Normal." ); // 静的メンバーへの簡易アクセス (Using static)

}

}

}

Page 36: C# 6.0 Preview

参考 : beforeusing System;

class MyException : Exception

{

public enum Type

{ Normal, Abnormal }

public MyException(MyException.Type state = MyException.Type.Normal)

{

State = state;

}

public Type State { get; private set; }

}

class Program

{

static void Sub()

{

throw new MyException(MyException.Type.Abnormal);

}

static void Main()

{

try {

Sub();

} catch (MyException ex) {

if (ex.State == MyException.Type.Abnormal)

Console.WriteLine("catch block: Abnormal.");

else

Console.WriteLine("catch block: Normal." );

}

}

}

Page 37: C# 6.0 Preview

nameof 演算子 (Nameof expressions)using System.Console; // 静的メンバーへの簡易アクセス (Using static)

using System.ComponentModel;

class Program

{

static void Main()

{

var person = new Person { FirstName = "Steve", LastName = "Ballmer" };

person.PropertyChanged += (sender, e) => WriteLine(string.Format("{0} has changed.", e.PropertyName));

person.FirstName = "Satya" ;

person.FirstName = "Nadella";

}

}

public class ViewModelBase : INotifyPropertyChanged

{

public event PropertyChangedEventHandler PropertyChanged;

protected void RaisePropertyChanged(string propertyName)

{

if (PropertyChanged != null)

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

}

Page 38: C# 6.0 Preview

nameof 演算子 (Nameof expressions)class Person : ViewModelBase

{

string firstName = string.Empty;

public string FirstName

{

get { return firstName; }

set {

if (value != firstName) {

firstName = value;

RaisePropertyChanged(nameof(FirstName)); // nameof演算子 (Nameof expressions)

RaisePropertyChanged(nameof(FullName )); // nameof演算子 (Nameof expressions)

}

}

}

string lastName = string.Empty;

public string LastName

{

get { return lastName; }

set {

if (value != lastName) {

lastName = value;

RaisePropertyChanged(nameof(LastName)); // nameof 演算子 (Nameof expressions)

RaisePropertyChanged(nameof(FullName)); // nameof 演算子 (Nameof expressions)

}

}

}

public string FullName

{

get { return string.Format("{0} {1}", FirstName, LastName); }

}

}

Page 39: C# 6.0 Preview

参考 : before その 1using System;

using System.ComponentModel;

class Program

{

static void Main()

{

var person = new Person { FirstName = "Steve", LastName = "Ballmer" };

person.PropertyChanged += (sender, e) => Console.WriteLine(string.Format("{0} has changed.", e.PropertyName));

person.FirstName = "Satya";

person.FirstName = "Nadella";

}

}

class Person : INotifyPropertyChanged

{

public event PropertyChangedEventHandler PropertyChanged;

Page 40: C# 6.0 Preview

参考 : before その 1 string firstName = string.Empty;

string lastName = string.Empty;

public string FirstName

{

get { return firstName; }

set

{

if (value != firstName) {

firstName = value;

if (PropertyChanged != null) {

PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));

PropertyChanged(this, new PropertyChangedEventArgs("FullName" ));

}

}

}

}

public string LastName

{

get { return lastName; }

set

{

if (value != lastName) {

lastName = value;

if (PropertyChanged != null) {

PropertyChanged(this, new PropertyChangedEventArgs("LastName"));

PropertyChanged(this, new PropertyChangedEventArgs("FullName"));

}

}

}

}

public string FullName

{

get { return string.Format("{0} {1}", FirstName, LastName); }

}

}

Page 41: C# 6.0 Preview

参考 : before その 2using System;

using System.ComponentModel;

using System.Linq.Expressions;

using System.Runtime.CompilerServices;

class Program

{

static void Main()

{

var person = new Person { FirstName = "Steve", LastName = "Ballmer" };

person.PropertyChanged += (sender, e) => Console.WriteLine(string.Format("{0} has changed.", e.PropertyName));

person.FirstName = "Satya";

person.FirstName = "Nadella";

}

}

public static class PropertyChangedEventHandlerExtensions

{

public static void Raise(this PropertyChangedEventHandler onPropertyChanged, object sender, [CallerMemberName] string propertyName = "")

{

if (onPropertyChanged != null)

onPropertyChanged(sender, new PropertyChangedEventArgs(propertyName));

}

public static void Raise<PropertyType>(this PropertyChangedEventHandler onPropertyChanged, object sender, Expression<Func<PropertyType>> propertyExpression)

{ onPropertyChanged.Raise(sender, propertyExpression.GetMemberName()); }

static string GetMemberName<MemberType>(this Expression<Func<MemberType>> expression)

{ return ((MemberExpression)expression.Body).Member.Name; }

}

Page 42: C# 6.0 Preview

参考 : before その 2class Person : INotifyPropertyChanged

{

public event PropertyChangedEventHandler PropertyChanged;

string firstName = string.Empty;

string lastName = string.Empty;

public string FirstName

{

get { return firstName; }

set {

if (value != firstName) {

firstName = value;

PropertyChanged.Raise(this);

PropertyChanged.Raise(this, () => FullName);

}

}

}

public string LastName

{

get { return lastName; }

set {

if (value != lastName) {

lastName = value;

PropertyChanged.Raise(this);

PropertyChanged.Raise(this, () => FullName);

}

}

}

public string FullName

{

get { return string.Format("{0} {1}", FirstName, LastName); }

}

}

Page 43: C# 6.0 Preview

その他 (not yet)using System.Collections.Generic;

using System.Console; // 静的メンバーへの簡易アクセス (Using static)

class Program

{

static void Main()

{

// Index initializers

// Note: Index initializers have been previously previewed but do not work in the current CTP.

var numberNames = new Dictionary<string, string>

{

{ " 二 ", "two" },

{ " 三 ", "three" },

{ " 五 ", "five" }

};

//var numberNames = new Dictionary<string, string> {

// [" 二 "] = "two" ,

// [" 三 "] = "three",

// [" 五 "] = "five"

//};

//// Indexed member initializer (Withdrawn)

//var numberNames = new Dictionary<string, string> {

// $ 二 = "two" ,

// $ 三 = "three",

// $ 五 = "five"

//};

// Indexed member access (Withdrawn)

var numberName = numberNames[" 三 "];

// var numberName = numberNames.$ 三 ;

}

}

Page 44: C# 6.0 Preview

その他 (not yet)using System.Collections.Generic;

using System.Console; // 静的メンバーへの簡易アクセス (Using static)

class Program

{

static void Main()

{

// Binary literals (Planned)

// var bits = 0b00000100;

// Digit separators (Planned)

// var bits = 0b0010_1110;

// var hex = 0x00_2E;

// var dec = 1_234_567_890;

// Event initializers (Planned)

// new Customer { Notify += MyHandler };

// Params IEnumerable (Planned)

//int Avg(params IEnumerable<int> numbers) { … }

// String interpolation (Maybe)

// "\{p.First} \{p.Last} is \{p.Age} years old.“

}

}

Page 45: C# 6.0 Preview

C# 6.0 考察

Page 46: C# 6.0 Preview

これらははたして言語として正当な進化なのか ?

Page 47: C# 6.0 Preview

進化には理由がある何が進化を起こさせているのか

C# 6.0 の進化の理由は ?

Page 48: C# 6.0 Preview

どんな問題をどういうアプローチで

解こうとしているのか ?

テクノロジーの進化に対するいつもの問

Page 49: C# 6.0 Preview

他の言語の進化と比べてみよう

Page 50: C# 6.0 Preview

• Java 8のすべて - InfoQhttp://www.infoq.com/jp/news/2013/09/everything-about-java-8

• Everything about Java 8 - TechEmpower Bloghttp://www.techempower.com/blog/2013/03/26/everything-about-java-8/

• Java8 でのプログラムの構造を変える Optional - きしだのはてなhttp://d.hatena.ne.jp/nowokay/20130524

• Java8 とC# -  猫と C#について書く matarillo の雑記http://d.hatena.ne.jp/matarillo/20131217/p1

• C# 使いから見てうらやましい Java8 の default 実装の使い方 - ぐるぐる~http://bleis-tift.hatenablog.com/entry/java8-default-impl

• LINQ to Objects と Java8-Stream API の対応表 – Qiitahttp://qiita.com/amay077/items/9d2941283c4a5f61f302

Java8 との比較

Page 51: C# 6.0 Preview

•デフォルトメソッド

• Optional

(C#er としては、基本的に羨ましくないが )Java8 のちょっとだけ羨ましいところ

Page 52: C# 6.0 Preview

Java8 のデフォルトメソッド

public interface MyInterface {

void method1();

default void method2() {

System.out.println("MyInterface.method2 has called.");

}

}

public class MyClass implements MyInterface {

@Override

public void method1() {

System.out.println("MyClass.method1 has called.");

}

}

Page 53: C# 6.0 Preview

C# での例 :// 1.X の頃 の IEnumerable

public interface IEnumerator

{

object Current { get; }

bool MoveNext();

void Reset();

}

public interface IEnumerable

{

IEnumerator GetEnumerator();

}

// 2.0 以降ジェネリクスに

// でも互換性が必要なので……

public interface IEnumerator<out T> : IDisposable, IEnumerator

{

T Current { get; }

}

public interface IEnumerable<out T> : IEnumerable

{

IEnumerator<T> GetEnumerator();

}

Page 54: C# 6.0 Preview

結果、こんな残念なことに…… ( 悲報 )class MyCollection : IEnumerable<int>{ public IEnumerator<int> GetEnumerator() { yield return 2; yield return 3; yield return 5; }

IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }}

Page 55: C# 6.0 Preview

技術的負債 !

Page 56: C# 6.0 Preview

今更、仕方ない ?

Page 57: C# 6.0 Preview

Java8 の default が使えれば…

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T>

GetEnumerator();

default IEnumerator GetEnumerator() { return GetEnumerator(); }}

class MyCollection :

IEnumerable<int>{ public IEnumerator<int>

GetEnumerator() { yield return 2; yield return 3; yield return 5; }}

Page 58: C# 6.0 Preview

Java8 の Optional// こんなコードが…

void outoutAsName(String text)// text は null かも知れな

いとする

{ if (text != null) { String name = normalize(text);

// normalize は null を返す可能性があるとする

if (name != null && name.length() > 3) output(name); }}

Page 59: C# 6.0 Preview

Java8 の Optional// Optional を使うと…

void outoutAsName(String text)// text は null かも

知れないとする

{Optional.ofNullable(name)

.map(name -> normalize(name)) .filter(name -> text.length()

> 3) .ifPresent(name -> output(name));}

Page 60: C# 6.0 Preview

• C#6.0 の「 null 伝搬演算子」と似ている

•が、違う• Optional の方がより汎用的に使える• メンバーでなくても使える

• Optional の方がより汎用的な言語仕様• 多くの言語の Maybe モナドに近い

• 「 null 伝搬演算子」の方がコンパクトに記述できる

C#6.0 とのアプローチの違い

Page 61: C# 6.0 Preview

結果としてC#6.0 と同じような問題が解けているように見えるが…

Page 62: C# 6.0 Preview

C# の方がより具体的な問題を

実用的に解いている

Page 63: C# 6.0 Preview

Java の方が一般的・汎用的

Page 64: C# 6.0 Preview

C#6.0•具体的な問題を実用的に解いている

Java8•一般的な問題を汎用的に解いている

Page 65: C# 6.0 Preview

C#6.0 の進化は現実の C# プログラマーの

「こう書きたい」を叶えようと

している

Page 66: C# 6.0 Preview

Let’s enjoy C#!