• 
• 
• 
• 
• 
• http://blog.shos.info
• 
http://1drv.ms/1vcTMOp 
• 
http://1drv.ms/1vcTNSv
1. 
2. 
3.
6 
ジェネリック 
オブジェクト 
指向 
関数型 
dynamic 
非同期 
Roslyn 
C# 1.0 C# 2.0 C# 3.0 C# 4.0 C# 5.0 C# 6.0
7 
手続き型関数型 
オブジェクト指向 
class 
delegate 
ラムダ式 
拡張メソッド 
LINQ 
型推論 
ジェネリック 
動的型付け 
dynamic 
非同期 
async/ 
await 
Parallel 
C# 1.X C# 2.0 C# 3.0 C# 4.0 C# 5.0 
メタプログ 
ラミング 
Roslyn 
C# 6.0
• 
• 
•
• 
• http://roslyn.codeplex.com
• 
• 
• https://ufcpp.wordpress.com/2014/04/04/net-compiler- 
platform-roslyn-preview/ 
• 
• https://ufcpp.wordpress.com/2014/04/06/c-beforeafter/
• 
• http://xin9le.net/csharp-vnext
• 
• http://msdn.microsoft.com/ja-jp/ 
magazine/dn683793.aspx 
C# vNext (以下C# 6.0。ただし、非公式名称 
なので注意してください) をすぐに使用する予 
定がなくても、その機能を知れば、今すぐ導入 
する価値があると考えるでしょう。
• 
• http://www.codeproject.com/Articles/808 
732/Briefly-exploring-Csharp-new-features
• 
• http://roslyn.codeplex.com/wikipage?title= 
Language%20Feature%20Status 
• 
• http://www.codeplex.com/Download?Proje 
ctName=roslyn&DownloadId=894944
• 
• 
• 
• 
• 
• 
• 
• http://roslyn.codeplex.com/wikipage?title=Lan 
guage%20Feature%20Status
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 
Dim addrs = From c in Customers ' 
comments 
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 
Checked : x += 1 : End Checked Exists Maybe 
Unchecked blocks 
Field targets on 
autoprops 
<Field: Serializable> Property p 
As Integer 
Planned Planned 
Last edited Tue at 8:23 AM by madst, version 28
• 
• http://blogs.msdn.com/b/visualstudio/archive 
/2014/08/18/visual-studio-14-ctp-3- 
released.aspx
• 
<?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)Mic 
rosoft.Common.props" 
Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVe 
rsion)Microsoft.Common.props')" /> 
<PropertyGroup> 
…… 
<LangVersion>experimental</LangVersion> 
</PropertyGroup> 
…… 
</Project>
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 が無いのでスコープ外 
} 
}
using 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); 
} 
}
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); 
} 
}
using 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); 
} 
}
using 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 
}
using 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; } 
} 
}
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) 
} 
}
using 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); 
} 
}
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"); 
} 
}
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"); 
} 
}
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) 
} 
}
using 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); 
} 
} 
} 
} 
}
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(); 
} 
}
using 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(); 
} 
}
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) 
} 
} 
}
using 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." ); 
} 
} 
}
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)); 
} 
}
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); } 
} 
}
using 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;
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); } 
} 
}
using 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; } 
}
class 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); } 
} 
}
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.$三; 
} 
}
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.“ 
} 
}
• 
http://www.infoq.com/jp/news/2013/09/everything-about-java- 
8 
• 
http://www.techempower.com/blog/2013/03/26/everything 
-about-java-8/ 
• 
http://d.hatena.ne.jp/nowokay/20130524 
• 
http://d.hatena.ne.jp/matarillo/20131217/p1 
• 
http://bleis-tift.hatenablog.com/entry/java8-default-impl 
• 
http://qiita.com/amay077/items/9d2941283c4a5f61f302
• 
•
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."); 
} 
}
// 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(); 
}
class MyCollection : IEnumerable<int> 
{ 
public IEnumerator<int> GetEnumerator() 
{ 
yield return 2; 
yield return 3; 
yield return 5; 
} 
IEnumerator IEnumerable.GetEnumerator() 
{ return GetEnumerator(); } 
}
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; 
} 
}
// こんなコードが… 
void outoutAsName(String text) 
// text はnullかも知れないとする 
{ 
if (text != null) { 
String name = normalize(text); 
// normalize はnull を返す可能性があるとする 
if (name != null && name.length() > 3) 
output(name); 
} 
}
// Optional を使うと… 
void outoutAsName(String text) 
// text はnullかも知れないとする 
{ 
Optional.ofNullable(name) 
.map(name -> normalize(name)) 
.filter(name -> text.length() > 3) 
.ifPresent(name -> output(name)); 
}
• 
• 
• 
• 
• 
• 
•
C#6.0 
•具体的な 
問題を実 
用的に解 
いている 
Java8 
•一般的な 
問題を汎 
用的に解 
いている
C# 6.0 Preview
C# 6.0 Preview

C# 6.0 Preview

  • 2.
    • • • • • • http://blog.shos.info
  • 3.
    • http://1drv.ms/1vcTMOp • http://1drv.ms/1vcTNSv
  • 4.
  • 6.
    6 ジェネリック オブジェクト 指向 関数型 dynamic 非同期 Roslyn C# 1.0 C# 2.0 C# 3.0 C# 4.0 C# 5.0 C# 6.0
  • 7.
    7 手続き型関数型 オブジェクト指向 class delegate ラムダ式 拡張メソッド LINQ 型推論 ジェネリック 動的型付け dynamic 非同期 async/ await Parallel C# 1.X C# 2.0 C# 3.0 C# 4.0 C# 5.0 メタプログ ラミング Roslyn C# 6.0
  • 8.
  • 9.
  • 11.
    • • •https://ufcpp.wordpress.com/2014/04/04/net-compiler- platform-roslyn-preview/ • • https://ufcpp.wordpress.com/2014/04/06/c-beforeafter/
  • 12.
  • 13.
    • • http://msdn.microsoft.com/ja-jp/ magazine/dn683793.aspx C# vNext (以下C# 6.0。ただし、非公式名称 なので注意してください) をすぐに使用する予 定がなくても、その機能を知れば、今すぐ導入 する価値があると考えるでしょう。
  • 14.
    • • http://www.codeproject.com/Articles/808 732/Briefly-exploring-Csharp-new-features
  • 15.
    • • http://roslyn.codeplex.com/wikipage?title= Language%20Feature%20Status • • http://www.codeplex.com/Download?Proje ctName=roslyn&DownloadId=894944
  • 16.
    • • • • • • • • http://roslyn.codeplex.com/wikipage?title=Lan guage%20Feature%20Status
  • 17.
    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 Dim addrs = From c in Customers ' comments 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 Checked : x += 1 : End Checked Exists Maybe Unchecked blocks Field targets on autoprops <Field: Serializable> Property p As Integer Planned Planned Last edited Tue at 8:23 AM by madst, version 28
  • 18.
    • • http://blogs.msdn.com/b/visualstudio/archive /2014/08/18/visual-studio-14-ctp-3- released.aspx
  • 19.
    • <?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)Mic rosoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVe rsion)Microsoft.Common.props')" /> <PropertyGroup> …… <LangVersion>experimental</LangVersion> </PropertyGroup> …… </Project>
  • 21.
    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 が無いのでスコープ外 } }
  • 22.
    using System; usingSystem.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); } }
  • 23.
    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); } }
  • 24.
    using System; classEmployee { 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); } }
  • 25.
    using 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 }
  • 26.
    using System; classProgram { 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; } } }
  • 27.
    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) } }
  • 28.
    using System; publicstruct 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); } }
  • 29.
    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"); } }
  • 30.
    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"); } }
  • 31.
    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) } }
  • 32.
    using System; classPerson { 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); } } } } }
  • 33.
    using System; usingSystem.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(); } }
  • 34.
    using System; usingSystem.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(); } }
  • 35.
    using System; usingSystem.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) } } }
  • 36.
    using System; classMyException : 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." ); } } }
  • 37.
    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)); } }
  • 38.
    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); } } }
  • 39.
    using System; usingSystem.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;
  • 40.
    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); } } }
  • 41.
    using System; usingSystem.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; } }
  • 42.
    class 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); } } }
  • 43.
    using System.Collections.Generic; usingSystem.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.$三; } }
  • 44.
    using System.Collections.Generic; usingSystem.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.“ } }
  • 50.
    • http://www.infoq.com/jp/news/2013/09/everything-about-java- 8 • http://www.techempower.com/blog/2013/03/26/everything -about-java-8/ • http://d.hatena.ne.jp/nowokay/20130524 • http://d.hatena.ne.jp/matarillo/20131217/p1 • http://bleis-tift.hatenablog.com/entry/java8-default-impl • http://qiita.com/amay077/items/9d2941283c4a5f61f302
  • 51.
  • 52.
    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."); } }
  • 53.
    // 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(); }
  • 54.
    class MyCollection :IEnumerable<int> { public IEnumerator<int> GetEnumerator() { yield return 2; yield return 3; yield return 5; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }
  • 57.
    public interface IEnumerable<outT> : 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; } }
  • 58.
    // こんなコードが… voidoutoutAsName(String text) // text はnullかも知れないとする { if (text != null) { String name = normalize(text); // normalize はnull を返す可能性があるとする if (name != null && name.length() > 3) output(name); } }
  • 59.
    // Optional を使うと… void outoutAsName(String text) // text はnullかも知れないとする { Optional.ofNullable(name) .map(name -> normalize(name)) .filter(name -> text.length() > 3) .ifPresent(name -> output(name)); }
  • 60.
    • • • • • • •
  • 64.
    C#6.0 •具体的な 問題を実 用的に解 いている Java8 •一般的な 問題を汎 用的に解 いている