Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

C# 6.0 Preview

5,097 views

Published on

『Hokuriku.NET vol.15』
http://hokurikunet.doorkeeper.jp/events/13746
2014-08-30(土)
「酒の肴はC# vNext」の資料

Published in: Technology

C# 6.0 Preview

  1. 1. • • • • • • http://blog.shos.info
  2. 2. • http://1drv.ms/1vcTMOp • http://1drv.ms/1vcTNSv
  3. 3. 1. 2. 3.
  4. 4. 6 ジェネリック オブジェクト 指向 関数型 dynamic 非同期 Roslyn C# 1.0 C# 2.0 C# 3.0 C# 4.0 C# 5.0 C# 6.0
  5. 5. 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
  6. 6. • • •
  7. 7. • • http://roslyn.codeplex.com
  8. 8. • • • https://ufcpp.wordpress.com/2014/04/04/net-compiler- platform-roslyn-preview/ • • https://ufcpp.wordpress.com/2014/04/06/c-beforeafter/
  9. 9. • • http://xin9le.net/csharp-vnext
  10. 10. • • http://msdn.microsoft.com/ja-jp/ magazine/dn683793.aspx C# vNext (以下C# 6.0。ただし、非公式名称 なので注意してください) をすぐに使用する予 定がなくても、その機能を知れば、今すぐ導入 する価値があると考えるでしょう。
  11. 11. • • http://www.codeproject.com/Articles/808 732/Briefly-exploring-Csharp-new-features
  12. 12. • • http://roslyn.codeplex.com/wikipage?title= Language%20Feature%20Status • • http://www.codeplex.com/Download?Proje ctName=roslyn&DownloadId=894944
  13. 13. • • • • • • • • http://roslyn.codeplex.com/wikipage?title=Lan guage%20Feature%20Status
  14. 14. 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
  15. 15. • • http://blogs.msdn.com/b/visualstudio/archive /2014/08/18/visual-studio-14-ctp-3- released.aspx
  16. 16. • <?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>
  17. 17. 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 が無いのでスコープ外 } }
  18. 18. 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); } }
  19. 19. 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); } }
  20. 20. 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); } }
  21. 21. 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 }
  22. 22. 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; } } }
  23. 23. 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) } }
  24. 24. 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); } }
  25. 25. 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"); } }
  26. 26. 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"); } }
  27. 27. 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) } }
  28. 28. 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); } } } } }
  29. 29. 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(); } }
  30. 30. 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(); } }
  31. 31. 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) } } }
  32. 32. 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." ); } } }
  33. 33. 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)); } }
  34. 34. 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); } } }
  35. 35. 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;
  36. 36. 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); } } }
  37. 37. 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; } }
  38. 38. 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); } } }
  39. 39. 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.$三; } }
  40. 40. 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.“ } }
  41. 41. • 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
  42. 42. • •
  43. 43. 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."); } }
  44. 44. // 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(); }
  45. 45. class MyCollection : IEnumerable<int> { public IEnumerator<int> GetEnumerator() { yield return 2; yield return 3; yield return 5; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }
  46. 46. 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; } }
  47. 47. // こんなコードが… void outoutAsName(String text) // text はnullかも知れないとする { if (text != null) { String name = normalize(text); // normalize はnull を返す可能性があるとする if (name != null && name.length() > 3) output(name); } }
  48. 48. // Optional を使うと… void outoutAsName(String text) // text はnullかも知れないとする { Optional.ofNullable(name) .map(name -> normalize(name)) .filter(name -> text.length() > 3) .ifPresent(name -> output(name)); }
  49. 49. • • • • • • •
  50. 50. C#6.0 •具体的な 問題を実 用的に解 いている Java8 •一般的な 問題を汎 用的に解 いている

×