Visual Studio Code で C# コンソールアプリケーション実行とデバッグ
環境構築/実行
[1] .NET Core のサイトから .NET Core SDK
を install
※自分は下記から .NET Core SDK 1.1 RC4
を選択
github.com
[2] コマンドラインでテンプレートを作成
dotnet new console dotnet restore dotnet run
[3] デバッグ実行(F5)
C#7 の Taple を使ってみる
- VSC の 拡張機能 で NugetPackageManager をインストール
- コマンドパレット(Ctrl+Shift+P)から NugetPackageManager -> System.ValueTuple -> 4.3.0 を選択
※「preLaunchTask build
が見つかりませんでした」系の error が一度発生したが、VSC再起動で解決。
参考:
.NET Core のバージョンが難しい - しばやん雑記
Running C# 7 Code With Visual Studio Code Editor
【.NET Core 1.1】dotnet new コマンドで作成できるテンプレートのまとめ: Shion のブログ
Visual Studio Code でサクッと C# のコンソールアプリをデバッグしよう - Windows 編 - Xamarin 日本語情報
Tour of Heroes
The Hero Editor
app.components.ts
import { Component } from '@angular/core'; export class Hero { id: number; name: string; } @Component({ selector: 'my-app', template: ` <h1>Hello {{name}}</h1> <h2>{{hero.name}} details!!</h2> <div><label>id: </label>{{hero.id}}</div> <div> <label>name: </label> <input [(ngModel)]="hero.name" placeholder="name"> </div> ` }) export class AppComponent { name = 'Tour of Heroes'; hero: Hero = { id: 1, name: 'Windstorm' } }
app.modele.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; <- import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule, FormsModule ], <- declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
Master/Detail
app.component.ts
import { Component } from '@angular/core'; const HEROES: Hero[] = [ { id: 11, name: 'Mr. Nice' }, { id: 12, name: 'Narco' }, { id: 13, name: 'Bombasto' }, { id: 14, name: 'Celeritas' }, { id: 15, name: 'Magneta' }, { id: 16, name: 'RubberMan' }, { id: 17, name: 'Dynama' }, { id: 18, name: 'Dr IQ' }, { id: 19, name: 'Magma' }, { id: 20, name: 'Tornado' } ]; export class Hero{ id: number; name: string; } @Component({ selector: 'my-app', template: ` <h1>Tour of Heroes</h1> <h2>My Heroes</h2> <ul class="heroes"> <li *ngFor="let hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)"> <!-- each hero goes here --> <span class="badge">{{hero.id}}</span> {{hero.name}} </li> </ul> <div *ngIf="selectedHero"> <h2>{{selectedHero.name}} details!</h2> <div><label>id: </label>{{selectedHero.id}}</div> <div> <label>name: </label> <input [(ngModel)]="selectedHero.name" placeholder="name"/> </div> </div> `, styles: [` .selected { background-color: #CFD8DC !important; color: white; } .heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; } .heroes li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0; height: 1.6em; border-radius: 4px; } .heroes li.selected:hover { background-color: #BBD8DC !important; color: white; } .heroes li:hover { color: #607D8B; background-color: #DDD; left: .1em; } .heroes .text { position: relative; top: -3px; } .heroes .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0 0 4px; } `] }) export class AppComponent { title = 'Tour of Heroes'; public heroes = HEROES; selectedHero: Hero; onSelect(hero: Hero): void { this.selectedHero = hero; } }
Multiple Components
app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { HeroDetailComponent } from './hero-detail.component'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, HeroDetailComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
app.components.ts
import { Component } from '@angular/core'; import {Hero} from './hero'; const HEROES: Hero[] = [ { id: 11, name: 'Mr. Nice' }, { id: 12, name: 'Narco' }, { id: 13, name: 'Bombasto' }, { id: 14, name: 'Celeritas' }, { id: 15, name: 'Magneta' }, { id: 16, name: 'RubberMan' }, { id: 17, name: 'Dynama' }, { id: 18, name: 'Dr IQ' }, { id: 19, name: 'Magma' }, { id: 20, name: 'Tornado' } ]; @Component({ selector: 'my-app', template: ` <h1>Tour of Heroes</h1> <h2>My Heroes</h2> <ul class="heroes"> <li *ngFor="let hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)"> <!-- each hero goes here --> <span class="badge">{{hero.id}}</span> {{hero.name}} </li> </ul> <hero-detail [hero]="selectedHero"></hero-detail> `, styles: [` .selected { background-color: #CFD8DC !important; color: white; } .heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; } .heroes li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0; height: 1.6em; border-radius: 4px; } .heroes li.selected:hover { background-color: #BBD8DC !important; color: white; } .heroes li:hover { color: #607D8B; background-color: #DDD; left: .1em; } .heroes .text { position: relative; top: -3px; } .heroes .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0 0 4px; } `] }) export class AppComponent { title = 'Tour of Heroes'; public heroes = HEROES; selectedHero: Hero; onSelect(hero: Hero): void { this.selectedHero = hero; } }
hero-detail.component.ts
import { Component, Input } from '@angular/core'; import {Hero} from './hero'; @Component({ selector: 'hero-detail', template: ` <div *ngIf="hero"> <h2>{{hero.name}} details!</h2> <div><label>id: </label>{{hero.id}}</div> <div> <label>name: </label> <input [(ngModel)]="hero.name" placeholder="name"/> </div> </div> ` }) export class HeroDetailComponent { @Input() hero: Hero; }
hero.ts
export class Hero { id: number; name: string; }
Services
hero.service.ts
import { Injectable } from '@angular/core'; import { Hero } from './hero'; import { HEROES } from './mock-heroes'; @Injectable() export class HeroService { getHeroes(): Promise<Hero[]> { return Promise.resolve(HEROES); } }
app.component.ts
import { Component, OnInit } from '@angular/core'; import { Hero } from './hero'; import { HeroService } from './hero.service'; @Component({ selector: 'my-app', template: ` <h1>Tour of Heroes</h1> <h2>My Heroes</h2> <ul class="heroes"> <li *ngFor="let hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)"> <!-- each hero goes here --> <span class="badge">{{hero.id}}</span> {{hero.name}} </li> </ul> <hero-detail [hero]="selectedHero"></hero-detail> `, styles: [` .selected { background-color: #CFD8DC !important; color: white; } .heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; } .heroes li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0; height: 1.6em; border-radius: 4px; } .heroes li.selected:hover { background-color: #BBD8DC !important; color: white; } .heroes li:hover { color: #607D8B; background-color: #DDD; left: .1em; } .heroes .text { position: relative; top: -3px; } .heroes .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0 0 4px; } `], providers: [HeroService] }) export class AppComponent implements OnInit { title = 'Tour of Heroes'; heroes: Hero[]; selectedHero: Hero; constructor (private heroService: HeroService) { } getHeroes(): void { this.heroService.getHeroes().then(heroes => this.heroes = heroes); } ngOnInit(): void { this.getHeroes(); } onSelect(hero: Hero): void { this.selectedHero = hero; } }
mock-heroes.ts
import { Hero } from './hero'; export const HEROES: Hero[] = [ { id: 11, name: 'Mr. Nice' }, { id: 12, name: 'Narco' }, { id: 13, name: 'Bombasto' }, { id: 14, name: 'Celeritas' }, { id: 15, name: 'Magneta' }, { id: 16, name: 'RubberMan' }, { id: 17, name: 'Dynama' }, { id: 18, name: 'Dr IQ' }, { id: 19, name: 'Magma' }, { id: 20, name: 'Tornado' } ];
Routing
Routing に関しては、理解するのに時間が掛かった。
重要だと思う部分を列挙してみる。
server-side rendering で言うと、Controller に近いのかな。
コード内の不明な箇所は F12 (VisualStudioCode) で定義に移動して行くと繋がりが見えてくる気がする!
- Routing is another name for navigation. The router is the mechanism for navigating from view to view.
Routing はナビゲーションの別の名前。Router は View と View を繋ぐメカニズム。 - RouterModuleは、外部オプションなので package のような形で読み込む
- Routing 専用のクラスは RoutingModule へ
Router outlet
Route は Path を HeroRoute に一致させ、HeroesComponentを表示させる。 ただし、Router にコンポーネントの表示先を伝える必要があるため、テンプレートの最後に <router-outlet> 要素を追加する。 RouterOutlet は、RouterModule によって提供されるディレクティブの1つである。
app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { DashboardComponent } from './dashboard.component'; import { HeroDetailComponent } from './hero-detail.component'; import { HeroesComponent } from './heroes.component'; import { HeroService } from './hero.service'; import { AppRoutingModule } from './app-routing.module'; @NgModule({ imports: [ BrowserModule, FormsModule, AppRoutingModule ], declarations: [ AppComponent, DashboardComponent, HeroDetailComponent, HeroesComponent ], providers: [ HeroService ], bootstrap: [ AppComponent ] }) export class AppModule { }
app-routing.module.ts
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { DashboardComponent } from './dashboard.component'; import { HeroesComponent } from './heroes.component'; import { HeroDetailComponent } from './hero-detail.component'; const routes: Routes = [ { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, { path: 'dashboard', component: DashboardComponent }, { path: 'detail/:id', component: HeroDetailComponent }, { path: 'heroes', component: HeroesComponent } ]; @NgModule({ imports: [ RouterModule.forRoot(routes) ], exports: [ RouterModule ] }) export class AppRoutingModule {}
app.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>{{title}}</h1> <nav> <a routerLink="/dashboard" routerLinkActive="active">Dashboard</a> <a routerLink="/heroes" routerLinkActive="active">Heroes</a> </nav> <router-outlet></router-outlet> `, styleUrls: ['./app.component.css'], }) export class AppComponent { title = 'Tour of Heroes'; }
heroes.component.ts
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { Hero } from './hero'; import { HeroService } from './hero.service'; @Component({ selector: 'my-heroes', templateUrl: './heroes.component.html', styleUrls: [ './heroes.component.css' ] }) export class HeroesComponent implements OnInit { heroes: Hero[]; selectedHero: Hero; constructor( private router: Router, private heroService: HeroService) { } getHeroes(): void { this.heroService.getHeroes().then(heroes => this.heroes = heroes); } ngOnInit(): void { this.getHeroes(); } onSelect(hero: Hero): void { this.selectedHero = hero; } gotoDetail(): void { this.router.navigate(['/detail', this.selectedHero.id]); } }
hero.service.ts
import { Hero } from './hero'; import { HEROES } from './mock-heroes'; import { Injectable } from '@angular/core'; @Injectable() export class HeroService { getHeroes(): Promise<Hero[]> { return Promise.resolve(HEROES); } getHeroesSlowly(): Promise<Hero[]> { return new Promise(resolve => { // Simulate server latency with 2 second delay setTimeout(() => resolve(this.getHeroes()), 2000); }); } getHero(id: number): Promise<Hero> { return this.getHeroes() .then(heroes => heroes.find(hero => hero.id === id)); } }
async/await
async/await
について、理解するために書いてみた。
まだまだ、関連するメソッドや細かい仕様部分は調べつつ扱っていかなければ...
「非同期処理って何だろう?」の事始めにして、感覚を掴む記事になれば幸い
Point
async/await
はC# 5.0
から導入されたTask
と紐づく構文Task
は単なる手順書!async
は単なる非同期メソッド!await
はタスクの完了を待ち、取り出す!
これを抑えておけば、あとは下記のコードを見てもらえるとすぐ分かると思う。
asyncTask.Wait();
の部分とかコメントアウトするともっと体感できると思う
※メイン処理が早く終わってしまうので、待ち時間は10秒に変更
参考:
C# Task async, await の使い方 - mcommit's message
Taskを極めろ!async/await完全攻略 - Qiita
NOT EXISTSで差分抽出
サブクエリーが少なくとも1行を返す場合、EXISTS subquery は TRUE、NOT EXISTS subquery は FALSE。 下記の例は、aとbのテーブルの列名Aと列名Bを比較し一致しないものを返す。
例:
select * from テーブル名A as a where not exists ( select * from テーブル名B as b where a.列名A = b.列名B // 条件 ) and a.列名A' = xxx
開発DBに不正な値があり、それがどの子か特定した経緯。
EnumのTryParse
第1引数には変換する文字列を指定する。 第2引数には変換された値を受け取る型の変数を指定する。
Enum.Parse
とは異なり、例外をスローすることなく、変換できる。
Foo foo; if (!Enum.TryParse(bar.ToString(), out foo)) { throw new InvalidCastException($"Fooには定義されていない値が選択されてます"); }
コレクションが0の場合の Max() について
Max()を扱う場合、コレクションが 0
の場合も考慮する必要がある
よって、例えば、下記のような形を使う
(new int[] { }).OrderByDescending(x => x).FirstOrDefault();
値型と参照型
値型/参照型、構造体/クラス備忘録
値型はオブジェクト内にインライン定義され、 参照型は、実データをヒープに格納する。
その型をどのように扱うかを考え、 多様性(ポリモーフィズム)を持つか否かを考える必要がある。
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace UnitTestProject1 { [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { // 値型 var valueType = new ValueType { value = 1 }; // 参照型 var classType = new ClassType { value = 1 }; Plus(valueType, classType); Assert.AreEqual(1, valueType.value); Assert.AreEqual(2, classType.value); } static void Plus(ValueType valueType, ClassType classType) { valueType.value += 1; classType.value += 1; } struct ValueType { public int value; } class ClassType { public int value; } } }