- 投稿日:2020-06-30T17:00:50+09:00
interfaceの利点について(初学者向け)
はじめに
こんちわす。はじめまして、Souと申します。
遅かれながら初めて記事を書くわけですが、悩んだ挙句、自分がPGする上で一番とっつきにくかった
interfaceについて書こうと思います。そもそも明確な利点がわからなかった経験があり、同じ悩みを抱えたエンジニアはいると思います。。
では実際にコードを見ながらアプローチしていきましょう。言語はc#で書きますが、スキル的に読むのは難しくないと思いますので一緒に頑張りましょう!利点 其の① メソッド名を強要出来る
よく聞くやつですね。最初は「それだけ??」と思うかもしれません。僕も最初はそうでした。
具体的には、"あらゆる変更に強くなる"という風に置き換えれます。例えば商品情報をデータベースから取得するという想定で考えましょう。
商品を識別できるユニークな値「id」を引数にし、それを条件に商品情報を取得するといったモノを想定してください。インターフェース
ISearchItemQuary.cspublic interface ISearchItemQuary { Item Execute(int id); }具象クラス
SearchItemQuaryFromDataBase.cspublic class SearchItemQuaryFromDataBase : ISearchItemQuary { public Item Execute(int id) { "データベースから商品情報取得処理;" } }実行クラス※使用するフレームワークであったりアーキテクチャによって実行クラスの名前は様々だと思うので今回は「Main」クラスにさせてください。
Main.cspublic class Main { private ISearchItemQuary _searchItemQuary; public Main (ISearchItemQuary searchItemQuary) { _searchItemQuary= searchItemQuary; } //実行処理 static void Main(string[] args) { //商品IDが1の商品情報を取得 _searchItemQuary.Execute(1); } }とします。
だが、ここでパフォーマンスなどの問題があってデータベースからではなくキャッシュサーバーから取得するように変更が必要になりました。
リファクタリングを行う上で大事なのは既存の処理を出来るだけ変えないことです。変更に強くなくてはなりません。では、さっそくキャッシュから取得するクラスを作りましょう。
SearchItemQuaryFromCache.cspublic class SearchItemQuaryFromCache : ISearchItemQuary { public Item Execute(int id) { "キャッシュサーバーから商品情報取得処理;" } }SearchItemQuaryFromDataBaseクラスと同じインターフェースISearchItemQuaryを使用します。
これによりExecuteメソッドを強要できます。
この時点でDBとCacheで同じメソッド名を持っていることを念頭に置いてください。これでリファクタリングは終わりです。同じインターフェースを噛ませているので、実行クラスで変える箇所はありません。
※Mainメソッドのコンストラクタの具象クラス(DBかCache)はDIコンテナで結びつけてると想定してください。
簡単に言うとインターフェースと具象クラスをアプリ起動時紐付けれるやつ。初学者の方はあまり気にしなくていいです。利点 其の② インスタンスを柔軟に選択できる
もう既に①の例で証明できてるのですが、もう一度確認してみましょう。
Main.cspublic Main (ISearchItemQuary searchItemQuary) { _searchItemQuary= searchItemQuary; }①でDBとCacheの2つのクラスを作成しましたが、前回も述べたようにクラスが増えたからといってMainクラスは何の変更もしていません。
理由はコンストラクタの引数がインターフェースで定義しているためです。
ISearchItemQuary を使用しているクラスであればこのMainクラスは誰でも使用することが出来ます。
まさに柔軟性が垣間見えた瞬間です!まとめ
まだまだ、TDD(テスト駆動開発)におけるインターフェースの使い方や、factory method、SOLID原則など
参考になるモノはあるので、初学者の方はこの辺からアプローチしてみてはいかがでしょうか?
- 投稿日:2020-06-30T14:55:45+09:00
UnityでXBOXコントローラーを振動させる
忘れそうなので自分用メモとして残しておきます。
Unity 2019.4で確認済みです。今回はこちらのXInputDotNetというライブラリを使用させていただきました。
とても助かりました。感謝。
https://github.com/speps/XInputDotNet.git手順
https://github.com/speps/XInputDotNet/releases
上にある最新のunityPackageをプロジェクトにインポートして
VibrationTest.csXInputDotNetPure.GamePad.SetVibration(0,5,5);この一行で振動してくれました。お手軽。
左右別々のモーターをそれぞれ動かすことができるようです。例
例えばこんな風にテスト用のスクリプトを書いてみました。
VibrationTest.csusing System.Collections; using UnityEngine; using XInputDotNetPure; public class VibrationTest : MonoBehaviour { [SerializeField] float right_power = 1; [SerializeField] float left_power = 1; [SerializeField] float duration = 0.5f; void Update() { if (Input.GetButtonDown("Fire1")) { StartCoroutine("RightVibration"); } if (Input.GetButtonDown("Fire2")) { StartCoroutine("LeftVibration"); } } IEnumerator RightVibration() { GamePad.SetVibration(0, 0, right_power); yield return new WaitForSecondsRealtime(duration); GamePad.SetVibration(0, 0, 0); } IEnumerator LeftVibration() { GamePad.SetVibration(0, left_power, 0); yield return new WaitForSecondsRealtime(duration); GamePad.SetVibration(0, 0, 0); } }今のところ0をセットすることで振動を止めていますが、これでいいのでしょうか…
参考
- 投稿日:2020-06-30T14:49:39+09:00
Octokitを使用してGithubのIssueを取得・追加する
はじめに
本記事は、GitHub APIとのやり取りを簡単にするためのライブラリであるOctokitを使用して得た知見をまとめることを目的としています。
事前準備
はじめに、GitHubにアクセスするためのトークンが必要なので作成します。
詳しいやり方はこちらがわかりやすいので参考にしてください。
なお、GitHubで作成したトークンは忘れてしまうと後で見ることができないので、使用するまではどこかに控えておいた方がいいです。
続いて、OctokitをNugetパッケージからインストールします。インストール先のプロジェクトをVisualStudio上で右クリックして、[NuGetパッケージの管理]をクリックします。参照タブを選択して[Octokit]と検索ボックスに入力すると先頭に出るので、画面右側のインストールボタンを押してインストールします。
GitHub Issueを取得・追加してみる
準備ができました。以下がGitHub Issueの取得・追加している実際のコードです。たった数行書くだけで簡単にできてしまいます。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Octokit; namespace DensoCreate.Lakewood.Extensions.GitHubIntegration.Services { /// <summary> /// GitHub Issueを取得・追加するために必要なサービスを提供するクラス /// </summary> public class GithubService { /// <summary> /// Github Issueを取得する /// </summary> /// <param name="settings">GitHubにアクセスするためのトークン、 /// Issueを取得するリポジトリを指定するための情報(リポジトリのオーナー名とリポジトリ名)</param> /// <returns>GitHub Issueのリスト</returns> public async Task<List<Issue>> GetIssues(GitHubExtensionSettings settings) { // 接続情報の設定 var tokenAuth = new Credentials(settings.Token); var client = new GitHubClient(new ProductHeaderValue("lr")) {Credentials = tokenAuth}; // GitHub Issueの取得 var gitHubIssues = new List<Issue>(); var issuesAsync = await client.Issue.GetAllForRepository(settings.Owner, settings.Repository); gitHubIssues = issuesAsync.ToList(); return gitHubIssues } /// <summary> /// Github IssueにIssueを追加する /// </summary> /// <param name="settings">GitHubにアクセスするためのトークン、 /// Issueを取得するリポジトリを指定するための情報(リポジトリのオーナー名とリポジトリ名)</param> /// <param name="issueTitle">Issueのタイトル</param> /// <param name="issueBody">Issueの本文</param> /// <returns></returns> public async Task AddIssue(GitHubExtensionSettings settings, string issueTitle, string issueBody) { // 接続情報の設定 var tokenAuth = new Credentials(settings.Token); var client = new GitHubClient(new ProductHeaderValue(settings.Owner)) {Credentials = tokenAuth}; // Issueを作成し、本文を設定 var createIssue = new NewIssue(issueTitle); createIssue.Body = issueBody; // Issueを追加 var newIssue = await client.Issue.Create(settings.Owner, settings.Repository, createIssue); } } }順番に解説したいと思います。
GitHubにアクセスするにはOctokitのGitHubClientのオブジェクトを作成する必要があります。GitHubClientのコンストラクタ引数にアプリケーション名を入れたProductHeaderValueオブジェクトを渡すことでGitHubへの接続が可能になります。
ただし、プライベートリポジトリへのアクセスやIssueの追加などをする場合にはユーザー認証が必要になるので、GitHubClientオブジェクトに認証情報(OctokitのCredentialsオブジェクト)を渡してやる必要があります。// 接続情報の設定 var tokenAuth = new Credentials(settings.Token); var client = new GitHubClient(new ProductHeaderValue("lr")) {Credentials = tokenAuth};以上で、GitHub Issueへのアクセスが可能になりました。
続いて、GitHub Issueの取得について説明します。
Octokitのデータ取得、追加、更新の各メソッドは全て非同期になっているので、それを前提にコード書く必要があります。GitHubClientオブジェクトのIssueのGetAllForRepositoryメソッドで引数にリポジトリのオーナーとリポジトリ名を指定することで、すべてのIssueを取得することができます。
// GitHub Issueの取得 var gitHubIssues = new List<Issue>(); var issuesAsync = await client.Issue.GetAllForRepository(settings.Owner, settings.Repository); gitHubIssues = issuesAsync.ToList();また、 RepositoryIssueRequestオブジェクトをGetAllForRepositoryメソッドの引数に指定することで取得するIssueにフィルタをかけることもできます。以下の例はOpenなIssueかつ特定のユーザーが Assignee に指定されているものを取得しています。
// GitHub Issueの取得 var gitHubIssues = new List<Issue>(); var assigneeFilter = new RepositoryIssueRequest { State = ItemState.Open, Assignee = username }; var issuesAsync = await client.Issue.GetAllForRepository(settings.Owner, settings.Repository, assigneeFilter); gitHubIssues = issuesAsync.ToList();最後に、GitHub Issueへの追加について説明します。
NewIssueオブジェクトのコンストラクタ引数にタイトル、Bodyに本文を設定することができます。なお、タイトルは必ず設定する必要があります。他にもAssignee、MileStoneやLabelを設定できます。ただし、MileStoneとLabelに関しては、あらかじめリポジトリ内に存在する必要があります。
GitHubClientオブジェクトのIssueのCreateメソッドにリポジトリのオーナー名、リポジトリ名、NewIssueオブジェクトを渡すことでIssueを追加できます。// Issueを作成し、本文を設定 var createIssue = new NewIssue(issueTitle); createIssue.Body = issueBody; // Issueを追加 var newIssue = await client.Issue.Create(settings.Owner, settings.Repository, createIssue);さいごに
今回はIssueの取得・追加を簡単にまとめてみました。すごく簡単にGitHubへアクセスできるので、興味のある方は是非お試しください。Githubへのコミットなどまだまだできることはありますので、色々試してみてください!
参考サイト
https://github.com/octokit/octokit.net
https://octokitnet.readthedocs.io/en/latest/issues/
- 投稿日:2020-06-30T14:14:33+09:00
NPocoの紹介 -カスタマイズ編- 空文字列をnullに変換して登録する
NPocoの紹介 -カスタマイズ編- 空文字列をnullに変換して登録する
最初の記事はこちら
今回はカスタマイズ方法についての紹介です。
注意
このカスタマイズ方法は公式で紹介されているものではなく、私が独自で行っているものです。
あらかじめご注意ください。
やること
InsertやUpdateにおいてパラメータに空文字列が含まれていた場合、これをnullに変換して登録する。
(「複数DBベンダー対応をする際にOracleの挙動に合わせるため」 などが動機として考えられます。
というか私はそれでした?)方法1
Database
クラスのAddParameter
をオーバーライドする。一つ目の方法は
Database
クラスそのものを継承し、AddParameter
クラスの挙動を変更します。MyDatabase.cspublic class MyDatabase : Database { public MyDatabase(DbConnection connection) : base(connection) { } public override void AddParameter(DbCommand cmd, object value) { if (value is string s) { if (string.IsNullOrEmpty(s)) { //空文字列ならnullで親のメソッドを呼ぶ base.AddParameter(cmd, null); return; } } //それ以外はそのまま base.AddParameter(cmd, value); } }実行コード
using MyDatabase database = new MyDatabase(con); database.Insert(new Emp { EmpId = "EX01", FirstName = "", FamilyName = "", DeptCode = "X01", CreatedAt = new DateTime(2020, 6, 30), UpdatedAt = new DateTime(2020, 6, 30), });実行ログ
INSERT INTO "emp" ("emp_id","first_name","family_name","dept_code","created_at","updated_at") VALUES (@p0,@p1,@p2,@p3,@p4,@p5) -> @p0 [String] = "EX01" -> @p1 [DBNull] = "" -> @p2 [DBNull] = "" -> @p3 [String] = "X01" -> @p4 [DateTime] = "2020/06/30 0:00:00" -> @p5 [DateTime] = "2020/06/30 0:00:00"p1, p2が
[DBNull]
となっていることからnull
で登録されていることが確認できます。方法2
IMapper
のGetParameterConverter
を使用する。IMapper というインターフェースが用意されており、これを利用すると、データベースから結果を取り出すときや、データベースへ登録するときに 変換処理などを行うことが可能です。
今回はこの
IMapper
のGetParameterConverter
メソッドを利用します。このメソッドは前述の
Database.AddParameter
で実行されています。また
IMapper
を直接実装するのではなく、あらかじめ用意されたDefaultMapperを継承して作成します。MyMapper.cspublic class MyMapper : DefaultMapper { private readonly IDictionary<Type, Func<object, object>> _converters = new Dictionary<Type, Func<object, object>> { [typeof(string)] = s => string.IsNullOrEmpty((string)s) ? null : s, }; public override Func<object, object> GetParameterConverter(DbCommand dbCommand, Type sourceType) { if (_converters.TryGetValue(sourceType, out Func<object, object> converter)) { return converter; } return base.GetParameterConverter(dbCommand, sourceType); } }実行コード
using Database database = new Database(con); database.Mappers.Add(new MyMapper()); database.Insert(new Emp { EmpId = "EX01", FirstName = "", FamilyName = "", DeptCode = "X01", CreatedAt = new DateTime(2020, 6, 30), UpdatedAt = new DateTime(2020, 6, 30), });実行ログ
INSERT INTO "emp" ("emp_id","first_name","family_name","dept_code","created_at","updated_at") VALUES (@p0,@p1,@p2,@p3,@p4,@p5) -> @p0 [String] = "EX01" -> @p1 [DBNull] = "" -> @p2 [DBNull] = "" -> @p3 [String] = "X01" -> @p4 [DateTime] = "2020/06/30 0:00:00" -> @p5 [DateTime] = "2020/06/30 0:00:00"
Database.AddParameter
と同様の結果になっています。注意点
これらの方法ですが、全てのパラメータマッピング時に実行されるため、SELECTを実行する場合でも呼び出されてしまいます。
(アプリの仕様によってはこれが害になる可能性もあります。)またSELECT + INSERT, SELECT + UPDATE のようなパラメータを介さないものについてはこれらのメソッドが実行されてないので、変換は行われません。
- 投稿日:2020-06-30T13:54:08+09:00
いのべこ夏休みアドベントカレンダー 2020
はじめに
「いのべこ」とは、株式会社富士通システムズウェブテクノロジーの社内技術コミュニティで、「イノベーション推進コミュニティ」が略されたものです。
「いのべこ」の2020年夏企画として「いのべこ夏休みアドベントカレンダー」を企画しました。昨冬のアドベントカレンダー同様、参加者の皆さんで盛り上げていきましょう!
参考:富士通システムズウェブテクノロジーアドベントカレンダー 2019ルール
- 参加者:当社社員・派遣社員および富士通グループ社員に限らせて頂きます
- テーマ:「技術」に関することならなんでもOK
- 記事形式:自由です。Qiita、個人ブログ、YouTube、なんでもありです
- Fujitsu Way、Fujitsu Wayのサイトにある「ソーシャルメディアを利用する場合のルールとマナー」の記述を守るようにしましょう
- Qiitaのガイドラインも目を通しましょう
参加登録方法
- 記事の下方にある編集リクエスト機能を使い、参加したい日付に以下の項目を書いて送ってください
- 執筆者名(ペンネームでもOKです)
- タイトル(仮で大丈夫です)
- なるべく早く反映するようにします
- 後からでも修正可能です。同様にご連絡ください
- 毎週水曜日は、当社社員以外の優先枠とします(が、埋まり具合で見直しもあります)
記事作成後の登録方法
- 編集リクエストで記事のタイトルとURLを送ってください
- (できるだけ)当日までに記事を書いて登録してください
さいごに
このページの記述はUnityゆるふわサマーアドベントカレンダー 2019を運営された@nkjzmさんの下記記事を参考とさせていただきました。ありがとうございました!
2年連続で夏のアドカレ運営をやってみての感想 【ゆるふわアドカレ】いのべこ夏休みアドベントカレンダー 2020 記事一覧
Date 記事名 執筆者名 8/1(土) 先鋒やります。テーマは未定。 ikeda.hideya 8/2(日) (募集中) 8/3(月) 今回もスマスピで何か書く(仮) じゅげむ(今井 隆) 8/4(火) (募集中) 8/5(水) (募集中) 8/6(木) (募集中) 8/7(金) 検討中! takapom 8/8(土) (募集中) 8/9(日) (募集中) 8/10(月) Vue.jsでアプリを作って遊んでみた eight-cotton(八幡怜奈) 8/11(火) (募集中) 8/12(水) (募集中) 8/13(木) (募集中) 8/14(金) (募集中) 8/15(土) Scalaで作るなにか(Native CLIアプリ or Spring Bootアプリを検討中) @ishibashi-futoshi 8/16(日) (募集中) 8/17(月) Pivotal流の振り返り会、教えます! 小とろ(花岡 舜) 8/18(火) (募集中) 8/19(水) (募集中) 8/20(木) (募集中) 8/21(金) (募集中) 8/22(土) (募集中) 8/23(日) (募集中) 8/24(月) (募集中) 8/25(火) バッチの勉強とツール作成(仮) co33mu(藤谷美佐) 8/26(水) (募集中) 8/27(木) (募集中) 8/28(金) (募集中) 8/29(土) 何か書く(ネタ枠) George22e(筒井城治) 8/30(日) (募集中) 8/31(月) (募集中)
- 投稿日:2020-06-30T00:51:16+09:00
C#/.NET関連の雑多なメモ
wikipediaと被っている。
便利なオンラインサービス
オンラインコンパイラ
- sharplab
最新のコンパイラが使用できるが、実行は制限が非常に厳しい。
(コンパイルやアセンブラだけなら可)- try.NET
C# 7.3相当(2020/06/30時点)と思われるが、Span
は使用できない。- wandbox
.NET Core/Mono(mcs)が選べるが、.NET Coreの場合は実行に時間がかかる。- paiza.io
Mono 4.5?なので C# 6.0相当と思われるAPIなど
- .NET API Catalog
API毎に対応しているバージョンがわかる- DotNetApis
NuGetのパッケージ内のAPI検索- .NET Standard 2.0から2.1へのAPI差分(diff)
- .NET Core 2.2から3.0へのAPI差分(diff)
- .NET Coreの破壊的変更
各ソースコード
- CoreCLRのCoreLib
- CoreFX(BCL)のCoreLib
- .NET Framework referencesource
ライセンスはMICROSOFT REFERENCE SOURCE LICENSE- .NET Framework referencesource@github
ライセンスはMITツール
フリーの逆コンパイラ
- ILSpy (Microsoft Store版)
- dnSpy
- Telerik JustDecompile
- Ildasm.exe
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\ildasm.exe"
スクリプティング
- C# Interactive
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn\csi.exe"
(WindowsTerminalなら"commandline": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\MSBuild\\Current\\Bin\\Roslyn\\csi.exe"
)- LINQPad
バージョン
Symbolを使用して、ソースコード中で
#if NETCOREAPP3_1
のように判定できる。
TargetFramework ターゲット フレームワーク モニカー (TFM) Symbol 既定のバージョン .NET Framework NETFRAMEWORK
net20 NET20
7.3 1 net35 NET35
7.3 1 net40 NET40
7.3 1 net45 NET45
7.3 1 net451 NET451
7.3 1 net452 NET452
7.3 1 net46 NET46
7.3 1 net461 NET461
7.3 1 net462 NET462
7.3 1 net47 NET47
7.3 1 net471 NET471
7.3 1 net472 NET472
7.3 1 net48 NET48
7.3 1 .NET Standard NETSTANDARD
netstandard1.0 NETSTANDARD1_0
7.3 netstandard1.1 NETSTANDARD1_1
7.3 netstandard1.2 NETSTANDARD1_2
7.3 netstandard1.3 NETSTANDARD1_3
7.3 netstandard1.4 NETSTANDARD1_4
7.3 netstandard1.5 NETSTANDARD1_5
7.3 netstandard1.6 NETSTANDARD1_6
7.3 netstandard2.0 NETSTANDARD2_0
7.3 netstandard2.1 NETSTANDARD2_1
8.0 .NET Core NETCOREAPP
netcoreapp1.0 NETCOREAPP1_0
netcoreapp1.1 NETCOREAPP1_1
netcoreapp2.0 NETCOREAPP2_0
7.3 netcoreapp2.1 NETCOREAPP2_1
7.3 netcoreapp2.2 NETCOREAPP2_2
7.3 netcoreapp3.0 NETCOREAPP3_0
8.0 netcoreapp3.1 NETCOREAPP3_1
8.0 言語仕様
本家
https://github.com/dotnet/csharplang
ECMA(C# 5.0)
https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-334.pdf
JISX3015(C# 1.2相当)
https://www.jisc.go.jp/app/jis/general/GnrJISNumberNameSearchList?show&jisStdNo=X3015
docs.microsoft.com(日本語)
https://github.com/dotnet/csharplang.ja-jp から生成されている。
- C# 6.0 のドラフト仕様
- C# 7.0 仕様の提案
- C# 7.1 仕様の提案
- C# 7.2 仕様の提案
- C# 7.3 仕様の提案
- C# 8.0 の新機能
歴史
- C# 8.0 - .NET Core 3.0 and Visual Studio 2019 version 16.3
- C# 7.3 - Visual Studio 2017 version 15.7
- C# 7.2 - Visual Studio 2017 version 15.5
- C# 7.1 - Visual Studio 2017 version 15.3
- C# 7.0 - Visual Studio 2017
- C# 6 - Visual Studio 2015
- C# 5 - Visual Studio 2012
- C# 4 - Visual Studio 2010
- C# 3 - Visual Studio 2008
- C# 2 - Visual Studio 2005
- C# 1.2 - Visual Studio .NET 2003
- C# 1.0 - Visual Studio .NET 2002
小ネタ
- [小ネタ]C#には8進数リテラルはない
- unsafeコンテキスト以外でIntPtrからSpanまたはReadOnlySpanに変換する方法は無い。(2019/1現在)
- unsafeコンテキスト以外でIntPtrからSpanまたはReadOnlySpanに無理矢理変換する方法
- P/Invokeのref(またはout)引数にnullを渡す
- [小ネタ] IntPtr型の省略可能引数には、new IntPtr()を使う
- ref readonly(inパラメーター修飾子)からReadOnlySpanを構築する
- [C#7.2] unsafeステートメントにもマーシャラーにも頼らないで、固定サイズ配列を含む構造体をP/Invokeで受け渡しする方法
古いcsproj形式では個別指定 ↩
- 投稿日:2020-06-30T00:51:16+09:00
俺用のC#関連メモ
wikipediaと被っている。
便利なオンラインサービス
オンラインコンパイラ
- sharplab
最新のコンパイラが使用できるが、実行は制限が非常に厳しい。
(コンパイルやアセンブラだけなら可)- try.NET
C# 7.3相当(2020/06/30時点)と思われるが、Span
は使用できない。- wandbox
.NET Core/Mono(mcs)が選べるが、.NET Coreの場合は実行に時間がかかる。- paiza.io
Mono 4.5?なので C# 6.0相当と思われるAPIなど
- .NET API Catalog
API毎に対応しているバージョンがわかる- DotNetApis
NuGetのパッケージ内のAPI検索- .NET Standard 2.0から2.1へのAPI差分(diff)
- .NET Core 2.2から3.0へのAPI差分(diff)
- .NET Coreの破壊的変更
各ソースコード
- CoreCLR
- CoreFX(BCL)
- .NET Framework referencesource
ライセンスはMICROSOFT REFERENCE SOURCE LICENSE- .NET Framework referencesource@github
ライセンスはMITツール
フリーの逆コンパイラ
- ILSpy (Microsoft Store版)
- dnSpy
- Telerik JustDecompile
- Ildasm.exe
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\ildasm.exe"
スクリプティング
- C# Interactive
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn\csi.exe"
(WindowsTerminalなら"commandline": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\MSBuild\\Current\\Bin\\Roslyn\\csi.exe"
)バージョン
Symbolを使用して、ソースコード中で
#if NETCOREAPP3_1
のように判定できる。
TargetFramework ターゲット フレームワーク モニカー (TFM) Symbol 既定のバージョン .NET Framework NETFRAMEWORK
net20 NET20
7.3 1 net35 NET35
7.3 1 net40 NET40
7.3 1 net45 NET45
7.3 1 net451 NET451
7.3 1 net452 NET452
7.3 1 net46 NET46
7.3 1 net461 NET461
7.3 1 net462 NET462
7.3 1 net47 NET47
7.3 1 net471 NET471
7.3 1 net472 NET472
7.3 1 net48 NET48
7.3 1 .NET Standard NETSTANDARD
netstandard1.0 NETSTANDARD1_0
7.3 netstandard1.1 NETSTANDARD1_1
7.3 netstandard1.2 NETSTANDARD1_2
7.3 netstandard1.3 NETSTANDARD1_3
7.3 netstandard1.4 NETSTANDARD1_4
7.3 netstandard1.5 NETSTANDARD1_5
7.3 netstandard1.6 NETSTANDARD1_6
7.3 netstandard2.0 NETSTANDARD2_0
7.3 netstandard2.1 NETSTANDARD2_1
8.0 .NET Core NETCOREAPP
netcoreapp1.0 NETCOREAPP1_0
netcoreapp1.1 NETCOREAPP1_1
netcoreapp2.0 NETCOREAPP2_0
7.3 netcoreapp2.1 NETCOREAPP2_1
7.3 netcoreapp2.2 NETCOREAPP2_2
7.3 netcoreapp3.0 NETCOREAPP3_0
8.0 netcoreapp3.1 NETCOREAPP3_1
8.0 言語仕様
本家
https://github.com/dotnet/csharplang
ECMA(C# 5.0)
https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-334.pdf
JISX3015(C# 1.2相当)
https://www.jisc.go.jp/app/jis/general/GnrJISNumberNameSearchList?show&jisStdNo=X3015
docs.microsoft.com(日本語)
https://github.com/dotnet/csharplang.ja-jp から生成されている。
- C# 6.0 のドラフト仕様
- C# 7.0 仕様の提案
- C# 7.1 仕様の提案
- C# 7.2 仕様の提案
- C# 7.3 仕様の提案
- C# 8.0 仕様の提案
歴史
- C# 8.0 - .NET Core 3.0 and Visual Studio 2019 version 16.3
- C# 7.3 - Visual Studio 2017 version 15.7
- C# 7.2 - Visual Studio 2017 version 15.5
- C# 7.1 - Visual Studio 2017 version 15.3
- C# 7.0 - Visual Studio 2017
- C# 6 - Visual Studio 2015
- C# 5 - Visual Studio 2012
- C# 4 - Visual Studio 2010
- C# 3 - Visual Studio 2008
- C# 2 - Visual Studio 2005
- C# 1.2 - Visual Studio .NET 2003
- C# 1.0 - Visual Studio .NET 2002
小ネタ
- [小ネタ]C#には8進数リテラルはない
- unsafeコンテキスト以外でIntPtrからSpanまたはReadOnlySpanに変換する方法は無い。(2019/1現在)
- unsafeコンテキスト以外でIntPtrからSpanまたはReadOnlySpanに無理矢理変換する方法
- P/Invokeのref(またはout)引数にnullを渡す
- [小ネタ] IntPtr型の省略可能引数には、new IntPtr()を使う
- ref readonly(inパラメーター修飾子)からReadOnlySpanを構築する
- [C#7.2] unsafeステートメントにもマーシャラーにも頼らないで、固定サイズ配列を含む構造体をP/Invokeで受け渡しする方法
古いcsproj形式では個別指定 ↩
- 投稿日:2020-06-30T00:20:32+09:00
Unity メモ
キー入力
Input.GetKeyDown( KeyCode.Space );カメラをプレイヤーに追従させる
CameraController.cspublic class CameraController : MonoBehaviour { GameObject player; void Start() { this.player = GameObject.Find("player"); } void Update() { Vector3 playerPos = this.player.transform.position; transform.position = new Vector3( transform.position.x, playerPos.y, transform.position.z ); } }
- 投稿日:2020-06-30T00:03:44+09:00
ViewからControllerに自作のクラスのListを送る方法
View
Index.cshtml<form id="mainForm"> <div class="container"> <div class="form-group row"> <label for="" class="col-sm-2 col-form-label">読込Excel:</label> <div class="col-sm-10"> <input type="text" class="form-control" id="readPath" name="ReadPath" > </div> </div> </div> <div class="container"> <div class="form-group row"> <label for="" class="col-sm-2 col-form-label">出力Excel:</label> <div class="col-sm-10"> <input type="text" class="form-control" id="outputPath" name="OutputPath" > </div> </div> </div> <div id="Processes"> <div class="container"> <div class="form-group row"> <label for="" class="col-sm-2 col-form-label">処理内容:</label> <div class="col-sm-10"> <select id="shori" class="form-control"> <option></option> <option>書き込み</option> </select> <p class="form-inline"> <input type="text" class="form-control" id="argument1" style="width:19.6%" readonly="readonly"> <input type="text" class="form-control" id="argument2" style="width:19.6%" readonly="readonly"> <input type="text" class="form-control" id="argument3" style="width:19.6%" readonly="readonly"> <input type="text" class="form-control" id="argument4" style="width:19.6%" readonly="readonly"> <input type="text" class="form-control" id="argument5" style="width:19.6%" readonly="readonly"> </p> </div> </div> </div> </div> </form> <footer> <div class="container"> <div align="right"> <button id="execute" class="btn-square-shadow">実行</button> </div> </div> </footer>Script
Execute.js$('#execute').click(function () { var processes = new Array(); var process = { Shori: $('#shori').val(), Arg1: $('#argument1').val(), Arg2: $('#argument2').val(), Arg3: $('#argument3').val(), Arg4: $('#argument4').val(), Arg5: $('#argument5').val(), }; processes.push(process); var model = { ReadPath: $('#readPath').val(), OutputPath: $('#outputPath').val(), }; model.Processes = processes; $.ajax({ contentType: "application/json", data: JSON.stringify(model), type: "POST", url: "/Home/btnExecute_Click", success: function () { console.log('成功'); }, error: function () { console.log('失敗'); } }) });Model
Parent.cspublic class Parent { public string ReadPath { get; set; } public string OutputPath { get; set; } public List<Process> Processes { get; set; } }Process.cspublic class Process { public string Shori { get; set; } public string Arg1 { get; set; } public string Arg2 { get; set; } public string Arg3 { get; set; } public string Arg4 { get; set; } public string Arg5 { get; set; } }Controller
HelloController.cspublic void btnExecute_Click(Parent parent) { // なんかしらの処理 return; }ポイント
・Modelのプロパティ名とScriptの変数名(プロパティ名)を合わせること
・Script側のListを変数に格納する場合は変数宣言時とは別にすること(↓)var model = { ReadPath: $('#readPath').val(), OutputPath: $('#outputPath').val(), }; model.Processes = processes;