20200409のC#に関する記事は12件です。

お手軽Linux Guiアプリ開発 初級 前編

お手軽Linux Guiアプリ開発 初級 前編

  1. Sqlite3の利用
  2. Dapperの導入 Dapperについてまとめてみた
  3. Dapper Extensionの導入 Dapperの拡張ライブラリ 比較検討
  4. Swaggerを使う Stoplight Studioなどを使う  本当に使ってよかったOpenAPI (Swagger) ツール
  5. C#からPythonを実行する C#からPythonスクリプトを呼び出す
  6. DataGrideViewとModelのバインディングの実現 URL treeView
  7. RazurebyPiへのデプロイの仕方

前編は5まで

Sample File

プロジェクトはGtk#を選択する

スクリーンショット 2020-04-09 19.34.07.png

Nugetからパッケージをダウンロードする

スクリーンショット 2020-04-09 19.36.00.png

ダウンロードするパッケージ

Dapper
DapperExtensions
Mono.Data.Sqliteをダウンロードします。Gtk2#の場合はSystem.Data.Sqliteは読み込めません。

スクリーンショット 2020-04-09 19.10.43.png

Dapperを使ったQuery

Queryの結果を自動でモデルに入れることができます。またInsert時Update時に引数代わりにModelを使えます。

        static public void _dapperTest() {

            Mono.Data.Sqlite.SqliteConnection connection = new Mono.Data.Sqlite.SqliteConnection();

            connection.ConnectionString = @"Data Source=パス/test.sqlite";
            connection.Open();

            var qurey = "select * from testTable;";

            var result = connection.Query<testTable>(qurey);
            foreach(var p in result) {
                Console.WriteLine("ID:" + p.test_id + " 名称:" + p.name);
            }

            connection.Close();
        }

DapperExtensionを使ったInsertUpdate処理

ModelからInsert文やUpdate文を自動生成し、処理できます

Sql文を生成を変更します
DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqliteDialect();

        static public void _dapperExtensionTest() {

            //Sql文を [testTable].[test_id]から [test_id]に変更する
            DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqliteDialect();

            Mono.Data.Sqlite.SqliteConnection connection = new Mono.Data.Sqlite.SqliteConnection();

            connection.ConnectionString = @"Data Source=パス/test.sqlite";
            connection.Open();

            //DapperExtensionを使った処理
            testTable testTable1 = new testTable();
            testTable1.name = "aaaaaa111";
            connection.Insert<testTable>(testTable1);

            var qurey = "select * from testTable;";
            var result = connection.QueryFirst<testTable>(qurey);

            //DapperExtensionを使った処理
            result.name += "qqqq111";
            connection.Update<testTable>(result);

            connection.Close();

        }

Swaggerを自動生成にさせる

SpotlitStudioを使います。

本当に使ってよかったOpenAPI (Swagger) ツール

スクリーンショット 2020-04-07 21.53.05.png

開発にあたってのポイント

  1. Gtk2#はMono.Data.Sqliteを使う。Dapperと併用できた
  2. gtkのサンプルを探すのに苦労した。C# gtk hotexamples 調べたいメソッド名で調べるとgitに上がっているサンプルを一覧できるサイトが見つけることができた。
  3. モデルにDataMemerを追加し、Dbのカラム名と変数名を紐づける(マッピング)

スクリーンショット 2020-04-09 13.42.35.png

後編に続く

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

お手軽Linux GUIアプリ開発 初級 前編

お手軽Linux GUIアプリ開発 初級 前編

  1. Sqlite3の利用
  2. Dapperの導入 Dapperについてまとめてみた
  3. Dapper Extensionの導入 Dapperの拡張ライブラリ 比較検討
  4. Swaggerを使う Stoplight Studioなどを使う  本当に使ってよかったOpenAPI (Swagger) ツール
  5. C#からPythonを実行する C#からPythonスクリプトを呼び出す
  6. DataGridViewとModelのバインディングの実現 URL treeView
  7. RaspberryPiへのデプロイの仕方

前編は5まで

Sample File

プロジェクトはGtk#を選択する

GTK#について

スクリーンショット 2020-04-09 19.34.07.png

Nugetからパッケージをダウンロードする

スクリーンショット 2020-04-09 19.36.00.png

ダウンロードするパッケージ

Dapper
DapperExtensions
Mono.Data.Sqliteをダウンロードします。Gtk2#の場合はSystem.Data.Sqliteは読み込めません。

スクリーンショット 2020-04-09 19.10.43.png

Dapperを使ったQuery

Dapper Tutorial

Queryの結果を自動でモデルに入れることができます。またInsert時Update時に引数代わりにModelを使えます。

        static public void _dapperTest() {

            Mono.Data.Sqlite.SqliteConnection connection = new Mono.Data.Sqlite.SqliteConnection();

            connection.ConnectionString = @"Data Source=パス/test.sqlite";
            connection.Open();

            var query = "select * from testTable;";

            var result = connection.Query<testTable>(query);
            foreach(var p in result) {
                Console.WriteLine("ID:" + p.test_id + " 名称:" + p.name);
            }

            connection.Close();
        }

DapperExtensionを使ったInsertUpdate処理

ModelからInsert文やUpdate文を自動生成し、処理できます

Sql文を生成を変更します

DapperExtensionについて

DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqliteDialect();
        static public void _dapperExtensionTest() {

            //Sql文を [testTable].[test_id]から [test_id]に変更する
            DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqliteDialect();

            Mono.Data.Sqlite.SqliteConnection connection = new Mono.Data.Sqlite.SqliteConnection();

            connection.ConnectionString = @"Data Source=パス/test.sqlite";
            connection.Open();

            //DapperExtensionを使った処理
            testTable testTable1 = new testTable();
            testTable1.name = "aaaaaa111";
            connection.Insert<testTable>(testTable1);

            var query = "select * from testTable;";
            var result = connection.QueryFirst<testTable>(query);

            //DapperExtensionを使った処理
            result.name += "qqqq111";
            connection.Update<testTable>(result);

            connection.Close();

        }

testTableモデル

  1. モデルにはGetter Setterを必ず書くこと
 public class testTable {

    public int test_id { get; set; }

    public string name { get; set; }
 }

Swaggerを自動生成にさせる

Stoplight Studioを使います。

本当に使ってよかったOpenAPI (Swagger) ツール

スクリーンショット 2020-04-07 21.53.05.png

開発にあたってのポイント

  1. Gtk2#はMono.Data.Sqliteを使う。Dapperと併用できた
  2. gtkのサンプルを探すのに苦労した。C# gtk hotexamples 調べたいメソッド名で調べるとgitに上がっているサンプルを一覧できるサイトが見つけることができた。
  3. モデルにはgetter setterを必ず書くこと

DataMapping

スクリーンショット 2020-04-09 13.42.35.png

後編に続く

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

眺めて覚えるXamarin Hello World

iPhoneの電池が持たなくなった。携帯電話の寿命は、大体3年ぐらいだ。

はたして5万円以上の値打ちがあるのかが疑問である。

そこでAndroidにすることにした。

image.png

さくさく動くし、電池も3日もつ!

値段も5万円から2万円適正価格だ!

前から気になっていたXamarinを使ってC#でプログラムしてみた。

1.Visual studio 2019のインストールについては、色々な記事があるので参考にしてほしい。
私の買ったディバイスは、UMIDIGI Xだ。まず、メーカサイトからディバイスドライバーをダウンロードしてWindows 10にinstall しよう。
image.png

ドライブが見えるようになる。
image.png

開発者モードにするには、「設定」アプリ内で「ビルド番号」を7回連続してタップ

image.png

image.png

Visual Studio 2019でプロジェクトを作成する。

image.png
Xamarin Formsを選択する。
Windows APPを作成するような感覚で開発できる。
image.png
空白のプロジェクトを作成する。
image.png

USBにより接続されたAndroidが表示されているか、確認する。
image.png
とりあえず下記のように表示されればOK
image.png
プログラムの内容を見てみよう
image.png
MainPage.xamlをダブルクリックするとソースが現れる。
XAMLはXMLをベースとしたマークアップ言語です。UIを定義するのに用いられます。

MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="HelloWorld.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <Label Text="Welcome to Xamarin.Forms!" 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
    </StackLayout>

</ContentPage>

さてプログラムでHello Worldを表示してみよう。
image.png

MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace HelloWorld
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            var layout = new StackLayout();
            var lb = new Label() { Text = "Hello World",FontSize=40 };
            layout.Children.Add(lb);
            this.Content = layout;

        }
    }
}

Xamlでうにゃうにゃ書いていたレアウトをプログラムで書くと上記のようになる。

多分、javaで書くよりすっきりしていて良い。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

眺めて覚える C# Xamarin Hello World

iPhoneの電池が持たなくなった。携帯電話の寿命は、大体3年ぐらいだ。

はたして5万円以上の値打ちがあるのかが疑問である。

そこでAndroidにすることにした。

image.png

さくさく動くし、電池も3日もつ!

値段も5万円から2万円適正価格だ!

前から気になっていたXamarinを使ってC#でプログラムしてみた。

1.Visual studio 2019のインストールについては、色々な記事があるので参考にしてほしい。
私の買ったディバイスは、UMIDIGI Xだ。まず、メーカサイトからディバイスドライバーをダウンロードしてWindows 10にinstall しよう。
image.png

ドライブが見えるようになる。
image.png

開発者モードにするには、「設定」アプリ内で「ビルド番号」を7回連続してタップ

image.png

image.png

Visual Studio 2019でプロジェクトを作成する。

image.png
Xamarin Formsを選択する。
Windows APPを作成するような感覚で開発できる。
image.png
空白のプロジェクトを作成する。
image.png

USBにより接続されたAndroidが表示されているか、確認する。
image.png
とりあえず下記のように表示されればOK
image.png
プログラムの内容を見てみよう
image.png
MainPage.xamlをダブルクリックするとソースが現れる。
XAMLはXMLをベースとしたマークアップ言語です。UIを定義するのに用いられます。

MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="HelloWorld.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <Label Text="Welcome to Xamarin.Forms!" 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
    </StackLayout>

</ContentPage>

さてプログラムでHello Worldを表示してみよう。
image.png

MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace HelloWorld
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            var layout = new StackLayout();
            var lb = new Label() { Text = "Hello World",FontSize=40 };
            layout.Children.Add(lb);
            this.Content = layout;

        }
    }
}

Xamlでうにゃうにゃ書いていたレアウトをプログラムで書くと上記のようになる。

多分、javaで書くよりすっきりしていて良い。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[完]Visual StudioとC#を初めて使ってブロック崩しゲームを作ってみた④

プレイ画面完成.gif

前回:Visual StudioとC#を初めて使ってブロック崩しゲームを作ってみた③

前回で一応完成していますが
今回はさらにゲームっぽくする為、機能追加します。


アウトライン

  • 設定ボタン追加
  • カウントダウン開始3秒
  • 経過中タイム表示
  • CLEAR表示(動きを付けたい)
  • ランキング表示(アプリ起動中)

ディティール

  • 設定ボタンの画面
    • ボール加速 on/off(ラジオボタン)
    • パドル移動距離 最大で1個分(スライドボタン)

CLEAR表示

気分でCLEAR表示作成から作っていきます!
JavaScriptで作れるようなポヨンポヨン動く文字を作りたかったのに
Windowsフォームじゃできない?みたいです。
なのでプロパティを活用して見た目をよくします。
CLEAR用のラベルだけ追加してサイズ、色、配置等はお任せです。
image.png
頑張っても古臭いデザインにしかなりませんでしたw

初期値でCLEARを入れているので、
ブロック数が1以上のときに文字を変更します。
以下をform3_loadメソッドに追加。

Form3.cs
            if (Form1.blockNum > 0)
            {
                label7.Text = "NotGood..";
                label7.ForeColor = Color.Black;
            }

イメージ↓
image.png

カウントダウン開始

これも数字が縮小していって次の数字を出したかったのですが難しいので
いや縮小させるだけならタイマーでサイズダウンさせましょう。

Form1で以下ラベル作成
プロパティのFontでサイズを大きくします。これは48pt
image.png

追加コードは以下になります。

Form1.cs
    public partial class Form1 : Form
    {
        Timer timerCount = new Timer(); //カウントダウンタイマー
        int countSize = 200; //カウント文字のサイズ
        int countNo = 3; //カウント数

        public Form1()
        {
            label1.Font = new Font(label1.Font.OriginalFontName, countSize + 1); //カウントダウン初期表示サイズ指定

            //カウントダウン開始
            timer.Interval = 100;
            timerCount.Tick += new EventHandler(countDown); //timer.Trik:Timer有効時に呼ばれる
            timerCount.Start();
        }

        private void countDown(object sender, EventArgs e)
        {
            if (countSize == 0)
            {
                countNo--;
                label1.Text = countNo.ToString();
                countSize = 200;
            }

            if (countSize == 20 && countNo == 1)
            {
                timerCount.Stop();

                //ゲームスタート
                countDownAfter();
            }
            countSize -= 20;
            label1.Font = new Font(label1.Font.OriginalFontName, countSize +1);
        }

        private void countDownAfter()
        {
            //ゲームタイマー
            timer.Interval = 33;
            timer.Tick += new EventHandler(Update); //timer.Trik:Timer有効時に呼ばれる
            timer.Start();

            //経過時間スタート
            keikaTime.Restart();
        }

①まずカウントダウン用のタイマーを作成
②タイマー有効時に呼ばれるcountDownメソッドを作成
③countDownAfterメソッド作成。カウントダウン後にゲームを開始するので
ゲーム中のタイマーと経過時間処理をそこへ移動。

フォントの変更の仕方結構調べました。
この記事に感謝します。https://qiita.com/r-ngtm/items/276a6ee832bd32afed36

実行してみます。
カウントダウン.gif

文字ボックスのサイズを小さくしているので値が小さくなるにつれて
左上に寄ってしまいます。
画面のXY軸を半分にすると画面の中心になります。
そこからカウントダウンのラベルサイズの半径を引くと
画面の中心に表示されるように「なります。

Form()とcountDown()でラベルをnewで作り出した後に位置を指定します。
「label1.Left」と「label1.Top 」の2行をそれぞれに追加します。

Form1.cs
public Form1()
        {
          label1.Font = new Font(label1.Font.OriginalFontName, countSize + 1); //カウントダウン初期表示サイズ指定
          label1.Left = (this.Width / 2) - (countSize / 2);
          label1.Top = (this.Height /2) - (countSize / 2);
・・・
private void countDown(object sender, EventArgs e)
        {
         label1.Font = new Font(label1.Font.OriginalFontName, countSize +1);
          label1.Left = (this.Width / 2) - (countSize / 2);
          label1.Top = (this.Height / 2) - (countSize / 2);

「コントロール名.Left」でX軸、TopでY軸を位置指定できます。

ラベルの四角い背景が後ろと被らないように透明にします。
Form1()のlabel1.Top処理の下に書きます。

Form1.cs
label1.BackColor = Color.Transparent; //背景透明化

カウントダウン完成.gif

経過中タイム表示

Form1にラベルを追加します。
image.png

新しくタイマーを作るのも面倒だじ、
定期処理のUpdate()に追加します。

Form1.cs
Form(){
label2.BackColor = Color.Transparent; //背景透明化
・・・
private void realTime() //リアルタイム表示
        {
            label2.Text = keikaTime.Elapsed.ToString().Substring(6, 6);
        }
・・・
private void Update(object sender, EventArgs e)
        {
            //リアルタイム
            realTime();

先ほどのlabel1の透明化処理の下にlabel2の透明化処理も書きます。
realTime()で表示するテキストを指定(リザルト画面の処理を丸パクリする)。

設定ボタン追加

ここでイメージしている画面は、スマホ版バトロワのエイム感度の設定画面
COD_SEN005.jpg
上の画面はタブ切り替えでページが切り替わります。
ユーザコントロールを利用してこれを作成します。

設定ボタンは後にして、先に設定画面を作ります。
Form4画面を追加します。
ツールボックス→すべてのWindowsフォーム→「TabControl」を画面に設置する。
テキストは対象タブを選択して、タブの画面エリア部をクリックし
そこからのプロパティでタブのテキストを変更できる(パドル距離・ボール加速)。
image.png

ツールボックス→すべてのWindowsフォーム→「TrackBar」を画面に設置する。
image.png
プロパティを変更します。Form4に記述するか、プロパティに直接打ちます。
trackBar1.Minimum = 1; //最小値
trackBar1.Maximum = 100; //最大値
trackBar1.Value = 50; //初期値
trackBar1.TickFrequency = 0; //メモリ刻む値
trackBar1.SmallChange = 1; //マウスで移動できる値
trackBar1.BackColor= Window; //とりあえず白く
trackBar1.TickStyle = Both; //つまみの形

参考→TrackBarの基本
メモリを刻むのは今どきダサいのでしませんw
以下のようになったはずです。
image.png
左右にボタン、下にラベルを設置します。
image.png
TrackBarのイベントを作成します。
プロパティ→イベント→MouseMoveにbar_Move入力。

Form4.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Breakout
{
    public partial class Form4 : Form
    {
        public static int paddleMove { get; set; } //パドル距離

        public Form4()
        {
            InitializeComponent();
            label1.Text = trackBar1.Value.ToString(); //距離初期値
        }

        //バー移動時
        private void bar_Move(object sender, EventArgs e)
        {
            label1.Text = trackBar1.Value.ToString();
            paddleMove = trackBar1.Value;
        }

        private void down_Click(object sender, EventArgs e)
        {
            trackBar1.Value --;
            bar_Move(sender, e);
        }

        private void up_Click(object sender, EventArgs e)
        {
            trackBar1.Value ++;
            bar_Move(sender, e);
        }
    }
}

Form2にて設定ボタン追加します。
image.png
プロパティのイベントのClickに「setting_Click」を入力しエンター押下。
以下の内容を追記

Form2.cs
private void option_Click(object sender, EventArgs e) //設定押下時
        {
            // Form4のインスタンスを生成
            Form4 form4 = new Form4();
            // form4を表示
            form4.ShowDialog();
        }

Form1のパドル移動処理(KeyPressed)を変更します。

Form1.cs
        private void KeyPressed(object sender, KeyPressEventArgs e) //押下毎
        {
            if (Form4.paddleMove == 0) //設定行っていない場合
            {
                Form4.paddleMove = 20;
            }
            if (e.KeyChar == 'a' && paddlePos.Left > 0) //A押下時
            {
                this.paddlePos.X -= Form4.paddleMove;
            }
            else if (e.KeyChar == 's' && paddlePos.Right < this.Width) //S押下時
            {
                this.paddlePos.X += Form4.paddleMove;
            }
        }

こんな感じで設定できるようになりましたね。
image.png

今回はここまで
残りは後日追記します。

未対応不具合メモ:
・スタート後画面閉じてもリザルト画面が表示される
・スタート前にパドル移動するとおかしな挙動

感想

ここまでお付き合いいただきありがとうございました!

Visual StudioとC#を使ってみて。
Eclipseより楽しいし簡単に作れる!
入門はJavaよりC#選ぶべきだったかも・・
ただWindowsフォームだとCSSとかJavaScriptがないのは不便。
動きを付けるのには向いてなく、
本当に業務システム向けだなって感じでした。

学びやすいからC#でスタートダッシュをして、
それから他の言語をやるのもありかと!
スコア毎にS~Dなどのランクをつけて表示するなど
色々いじって身につけるください!
1ファイルが長くなったり、ファイル数が増えてきたら
フォルダ―を追加したり共有ファイルを作ったりします。
実際の現場では何十何百とファイルがありますが
小分けにされているだけなので怖がらないように!

興味もない業務システム作るのはあんまり楽しくないなあ。。
(次の案件がVisual Studio(C#)...)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

お手軽Linux Guiアプリ開発 初級 前半

お手軽Linux Guiアプリ開発 初級 前半

開発内容

  1. GtkGUIでSqlite3を使う
  2. Dapperの導入 Dapperについてまとめてみた
  3. Dapper Extensionの導入 Dapperの拡張ライブラリ 比較検討
  4. Swaggerを使う Stoplight Studioなどを使う  使ってよかったOpenAPI (Swagger) ツール
  5. C#からPythonを実行する C#からPythonスクリプトを呼び出す
  6. DataGrideViewとModelのバインディングの実現 treeView
  7. RazurebyPiへのデプロイ

前半は5まで

Git URL

開発環境

Mac
VisualStudioMac 2019
C#
Sqlite3

VisualStudioMacにSqlite3の導入

NugetからSystem.Data.SQlite.Coreをインストールします
スクリーンショット 2020-04-07 14.39.40.png
スクリーンショット 2020-04-07 20.36.05.png

C#でSQLite3を使ってみる

Sqliteを実行する

using System;
using System.Data.SQLite;

namespace sqliteTest {
    class Program {

    static void Main(string[] args) {

            SQLiteConnection connection = new SQLiteConnection();
            SQLiteCommand command = new SQLiteCommand();

            connection.ConnectionString = @"Data Source=パス";
            connection.Open();

            command.CommandText = "select * from testTable;";
            command.Connection = connection;

            // SQLを実行します。
            SQLiteDataReader reader = command.ExecuteReader();

            while(reader.Read()) {
                var id = reader.GetValue(0);
                var name = reader.GetValue(1);
                Console.WriteLine("ID:" + id + " 名称:" + name );
            }
            connection.Close();
        }
    }
 }

Dapperの導入

クエリーの結果をモデルにフェッチできたり、insert,Update時に値をmodelで渡して処理できます

NugetからDapperを導入します

Dapperの導入 Dapperについてまとめてみた

スクリーンショット 2020-04-07 15.22.42.png

model.cs
public class testTable {
    public int test_id { get; set; }
    public string name { get; set; }
}
using System;
using System.Data.SQLite;
using Dapper;

namespace sqliteTest {
    class Program {

    static void Main(string[] args) {
            SQLiteConnection connection = new SQLiteConnection();

            connection.ConnectionString = @"Data Source=パス/test.sqlite";
            connection.Open();

            var qurey = "select * from testTable;";

            var result = connection.Query<testTable>(qurey);
            foreach(var p in result) {
                Console.WriteLine("ID:" + p.test_id + " 名称:" + p.name);
            }       
            connection.Close();
        }

    }
}

Dapper Extensionの導入

ModelからInsert文、Update文、Delete文を自動生成でき、実行できます

NugetからDapperExtensions.NetCoreを導入します

必須 Sql文を[testTable].[test_id]から [test_id]に変更します
DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqliteDialect();

Dapper Extensionの導入 Dapperの拡張ライブラリ 比較検討

using System;
using System.Data.SQLite;
using Dapper;
using DapperExtensions;

namespace sqliteTest {
    class Program {

    static void Main(string[] args) {

            //Sql文を [testTable].[test_id]から [test_id]に変更する
            DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqliteDialect();

            SQLiteConnection connection = new SQLiteConnection();
            connection.ConnectionString = @"Data Source=パス";
            connection.Open();

           //insert
            testTable testTable1 = new testTable();
            testTable1.name = "aaaaaa";
            connection.Insert<testTable>(testTable1);

            //Modelのフェッチ
            var qurey = "select * from testTable;";
            var result = connection.QueryFirst<testTable>(qurey);

            //update
            result.name += "testtest";
            connection.Update<testTable>(result);

            connection.Close();
        }

    }
}

C#からPythonを実行する

Pythonのパスを取得する

$ which python

/usr/local/bin/python

C#からPythonスクリプトを呼び出す

test.py
import sys

if len(sys.argv) == 3:
    firstArgument = int(sys.argv[1]) 
    secondArgument = int(sys.argv[2])
    print(firstArgument + secondArgument)
else:
    print('ArgumentException...')
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace sqliteTest {
    class Program {

    static void Main(string[] args) {

            var pythonInterpreterPath = @"パス/python";

            var pythonScriptPath = @"パス/test.py";

            var arguments = new List<string>
            {
            pythonScriptPath ,
            "20",   //第1引数
            "30"    //第2引数
        };

            var process = new Process() {
                StartInfo = new ProcessStartInfo(pythonInterpreterPath) {
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    Arguments = string.Join(" ", arguments),
                },
            };

            process.Start();

            //python側でprintした内容を取得
            var sr = process.StandardOutput;
            var result = sr.ReadLine();

            process.WaitForExit();
            process.Close();
            Console.WriteLine("Result is ... " + result);
        }    
    }
}

Swaggerの生成

Swaggerを作り。SwaggerCodegenでC#で書かれたAPIクライアントプログラムを生成します。

Stoplight Studioを使います

本当に使ってよかったOpenAPI (Swagger) ツール

Swaggerの概要をまとめてみた。

スクリーンショット 2020-04-07 21.53.05.png

DataGrideViewとModelのバインディンで表示

DataGrideViewとModelのバインディングの実現 treeView

簡単なデータベースアプリのプロト開発

https://www.monodevelop.com/documentation/
https://www.monodevelop.com/documentation/stetic-gui-designer/
https://ja.coder.work/so/gtktreeview
よい
https://www.mono-project.com/docs/gui/gtksharp/widgets/treeview-tutorial/

GTK C# hotexamples 調べたいメソッド名で検索するとかなりよい

スクリーンショット 2020-04-09 13.42.35.png

後半へ続く

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[コピペでOK] C#でログを出力する

はじめに

C#でログを出力するLoggerを作成しました。
C#では、便利なライブラリがありますが、
ここでは、コピペですぐに使えるものを目指しています。

機能としては下記の通りです。

  • ログレベル
  • ログローテート
  • 出力先指定

下記にC#でログ出力を行うライブラリを紹介しているリンクを記載します。

実行環境

今回実行した環境は下記の通りです。

実行環境
Microsoft .NET Framework 3.5

C#の古いバージョンでも動作するように実装しています。

使い方

使い方は下記の通りです。

Logger log = Logger.GetInstance();
log.Error("error log.");
log.Warn("warn log.");
log.Info("info log.");
log.Debug("debug log.");

出力されるログは下記の通りです。

[2020-04-08 22:38:56.081][1][DEBUG] debug log.
[2020-04-08 22:38:56.082][1][ERROR] error log.
[2020-04-08 22:38:56.082][1][WARN] warn log.
[2020-04-08 22:38:56.082][1][INFO] info log.

「1」この数字は、プロセスIDを表示しています。

Loggerの実装

configでLoggerに関する設定を行います。

app.config
<setting name="IS_LOGFILE" serializeAs="String">
    <value>True</value>
</setting>
<setting name="LOG_LEVEL" serializeAs="String">
    <value>3</value>
</setting>
<setting name="LOGDIR_PATH" serializeAs="String">
    <value>./logs/</value>
</setting>
<setting name="LOGFILE_NAME" serializeAs="String">
    <value>console</value>
</setting>
<setting name="LOGFILE_MAXSIZE" serializeAs="String">
    <value>10485760</value>
</setting>
<setting name="LOGFILE_PERIOD" serializeAs="String">
    <value>30</value>
</setting>
  • 「IS_LOGFILE」はログファイル出力フラグです。
  • 「LOG_LEVEL」はログレベルです。
  • 「LOGDIR_PATH」はログファイル出力ディレクトリです。
  • 「LOGFILE_NAME」はログファイル名です。
  • 「LOGFILE_MAXSIZE」はログファイル最大サイズ(Byte)です。
  • 「LOGFILE_PERIOD」はログ保存期間(日)です。

Loggerクラスの実装は下記の通りです。

Logger.cs
class Logger
{
    /// <summary>
    /// ログレベル
    /// </summary>
    private enum LogLevel
    {
        ERROR,
        WARN,
        INFO,
        DEBUG
    }

    private static Logger singleton = null;
    private readonly string logFilePath = null;
    private readonly object lockObj = new object();
    private StreamWriter stream = null;

    /// <summary>
    /// インスタンスを生成する
    /// </summary>
    public static Logger GetInstance()
    {
        if (singleton == null)
        {
            singleton = new Logger();
        }
        return singleton;
    }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    private Logger()
    {
        this.logFilePath = Settings.Default.LOGDIR_PATH + Settings.Default.LOGFILE_NAME + ".log";

        // ログファイルを生成する
        CreateLogfile(new FileInfo(logFilePath));
    }

    /// <summary>
    /// ERRORレベルのログを出力する
    /// </summary>
    /// <param name="msg">メッセージ</param>
    public void Error(string msg)
    {
        if ((int)LogLevel.ERROR <= Settings.Default.LOG_LEVEL)
        {
            Out(LogLevel.ERROR, msg);
        }
    }

    /// <summary>
    /// ERRORレベルのスタックトレースログを出力する
    /// </summary>
    /// <param name="ex">例外オブジェクト</param>
    public void Error(Exception ex)
    {
        if ((int)LogLevel.ERROR <= Settings.Default.LOG_LEVEL)
        {
            Out(LogLevel.ERROR, ex.Message + Environment.NewLine + ex.StackTrace);
        }
    }

    /// <summary>
    /// WARNレベルのログを出力する
    /// </summary>
    /// <param name="msg">メッセージ</param>
    public void Warn(string msg)
    {
        if ((int)LogLevel.WARN <= Settings.Default.LOG_LEVEL)
        {
            Out(LogLevel.WARN, msg);
        }
    }

    /// <summary>
    /// INFOレベルのログを出力する
    /// </summary>
    /// <param name="msg">メッセージ</param>
    public void Info(string msg)
    {
        if ((int)LogLevel.INFO <= Settings.Default.LOG_LEVEL)
        {
            Out(LogLevel.INFO, msg);
        }
    }

    /// <summary>
    /// DEBUGレベルのログを出力する
    /// </summary>
    /// <param name="msg">メッセージ</param>
    public void Debug(string msg)
    {
        if ((int)LogLevel.DEBUG <= Properties.Settings.Default.LOG_LEVEL)
        {
            Out(LogLevel.DEBUG, msg);
        }
    }

    /// <summary>
    /// ログを出力する
    /// </summary>
    /// <param name="level">ログレベル</param>
    /// <param name="msg">メッセージ</param>
    private void Out(LogLevel level, string msg)
    {
        if (Settings.Default.IS_LOGFILE)
        {
            int tid = System.Threading.Thread.CurrentThread.ManagedThreadId;
            string fullMsg = string.Format("[{0}][{1}][{2}] {3}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), tid, level.ToString(), msg);

            lock (this.lockObj)
            {
                this.stream.WriteLine(fullMsg);

                FileInfo logFile = new FileInfo(this.logFilePath);
                if (Settings.Default.LOGFILE_MAXSIZE < logFile.Length)
                {
                    // ログファイルを圧縮する
                    CompressLogFile();

                    // 古いログファイルを削除する
                    DeleteOldLogFile();
                }
            }
        }
    }

    /// <summary>
    /// ログファイルを生成する
    /// </summary>
    /// <param name="logFile">ファイル情報</param>
    private void CreateLogfile(FileInfo logFile)
    {
        if (!Directory.Exists(logFile.DirectoryName))
        {
            Directory.CreateDirectory(logFile.DirectoryName);
        }

        this.stream = new StreamWriter(logFile.FullName, true, Encoding.UTF8)
        {
            AutoFlush = true
        };
    }

    /// <summary>
    /// ログファイルを圧縮する
    /// </summary>
    private void CompressLogFile()
    {
        this.stream.Close();
        string oldFilePath = Settings.Default.LOGDIR_PATH + Settings.Default.LOGFILE_NAME + "_" + DateTime.Now.ToString("yyyyMMddHHmmss");
        File.Move(this.logFilePath, oldFilePath + ".log");

        FileStream inStream = new FileStream(oldFilePath + ".log", FileMode.Open, FileAccess.Read);
        FileStream outStream = new FileStream(oldFilePath + ".gz", FileMode.Create, FileAccess.Write);
        GZipStream gzStream = new GZipStream(outStream, CompressionMode.Compress);

        int size = 0;
        byte[] buffer = new byte[Settings.Default.LOGFILE_MAXSIZE + 1000];
        while (0 < (size = inStream.Read(buffer, 0, buffer.Length)))
        {
            gzStream.Write(buffer, 0, size);
        }

        inStream.Close();
        gzStream.Close();
        outStream.Close();

        File.Delete(oldFilePath + ".log");
        CreateLogfile(new FileInfo(this.logFilePath));
    }

    /// <summary>
    /// 古いログファイルを削除する
    /// </summary>
    private void DeleteOldLogFile()
    {
        Regex regex = new Regex(Settings.Default.LOGFILE_NAME + @"_(\d{14}).*\.gz");
        DateTime retentionDate = DateTime.Today.AddDays(-Settings.Default.LOGFILE_PERIOD);
        string[] filePathList = Directory.GetFiles(Settings.Default.LOGDIR_PATH, Settings.Default.LOGFILE_NAME + "_*.gz", SearchOption.TopDirectoryOnly);
        foreach (string filePath in filePathList)
        {
            Match match = regex.Match(filePath);
            if (match.Success)
            {
                DateTime logCreatedDate = DateTime.ParseExact(match.Groups[1].Value.ToString(), "yyyyMMddHHmmss", null);
                if (logCreatedDate < retentionDate)
                {
                    File.Delete(filePath);
                }
            }
        }
    }
}

スレッドセーフにするために、lockを使用しています。

さいごに

ソースコードをGitHubに公開しています。

ソースファイルはこちら

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]初心者 privateってなに?

環境

Unity 2019.3.7f1

privateってなに?

ざっくり簡単にいうと、変数やメソッドを他のスクリプトからアクセスさせないようにするもの
意図せず数値が書き換えられてしまうのを防止する

最初は、
privateは他からアクセスできない
publicは他からアクセスできる
と覚えておく程度でOK!

他のスクリプトで値を使う予定のない変数にはprivateをつけておけば無難。

privateは省略できる

初心者さんにはこれを一番伝えたい!

実は、変数宣言時にpublicやprivateなどの"アクセス修飾子"をつけないと
privateが省略されるかたちになっている

次の2つは同じ
image.png
↑privateが省略されている
image.png

他の記事を見る際は、
・privateを省略するパターン
・privateをあえて書くパターン
がありますので、この点を頭において見ていくと良いです。

私は最初これがわからずもやもやした気持ちで参考記事を見ていました。
楽しいUnityライフを!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]初心者 privateってなに?

環境

Unity 2019.3.7f1

privateってなに?

ざっくり簡単にいうと、変数やメソッドを他のスクリプトからアクセスさせないようにするもの
意図せず数値が書き換えられてしまうのを防止する

最初は、
privateは他からアクセスできない
publicは他からアクセスできる
と覚えておく程度でOK!

他のスクリプトで値を使う予定のない変数にはprivateをつけておけば無難。

privateは省略できる

初心者さんにはこれを一番伝えたい!

実は、変数宣言時にpublicやprivateなどの"アクセス修飾子"をつけないと
privateが省略されるかたちになっている

次の2つは同じ
image.png
↑privateが省略されている
image.png

他の記事を見る際は、
・privateを省略するパターン
・privateをあえて書くパターン
がありますので、この点を頭において見ていくと良いです。

私は最初これがわからずもやもやした気持ちで参考記事を見ていました。
楽しいUnityライフを!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Microsoft.Extensions.Configuration を使って、INI ファイルに書いた設定を読み込む

Microsoft.Extensions.Configuration を使って、INI ファイルに書いた設定を読み込む

exe.config はずっと微妙だなあと思っていたのですが、Microsoft 謹製の INI ファイルから設定を読む手段が提供されたので、それを使ってみる. 例として以下の INI ファイルを読むコードを作成する. 書いたコードは GitHub にも上げてある.

config.ini
[ConnectionStrings]
Database=xxx

[AppSettings]
UserName=foo
Password=bar
RetryCount=3

Console App (.NET Core) プロジェクトを作成する. TargetFramework が netcoreapp3.1 (.NET Core 3.1) で作成される. 要求は .NET Standard 2.0 なので .NET Framework 4.6.1 や、.NET Core 2.0 でも動くはず.

次に Microsoft.Extensions.Configuration.IniInstall-Package Microsoft.Extensions.Configuration.Binder を nuget インストールする. これを書いている時点では 3.1.3 がインストールされる.

Install-Package Microsoft.Extensions.Configuration.Ini
Install-Package Microsoft.Extensions.Configuration.Binder

そして、セクション毎に情報を詰めるクラスを書いていく.

ConnectionStringsConfig.cs
namespace ConsoleApp1
{
    public class ConnectionStringsConfig
    {
        public string Database { get; set; }
    }
}
AppSettingsConfig.cs
namespace ConsoleApp1
{
    public class AppSettingsConfig
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        public int RetryCount { get; set; }
    }
}

最後にそれらセクション毎のクラスをまとめ上げるクラスと、INI ファイルから設定を読み込むメソッドを書いて完成.

AppConfig.cs
using Microsoft.Extensions.Configuration;

namespace ConsoleApp1
{
    public class AppConfig
    {
        static AppConfig Instance;

        public ConnectionStringsConfig ConnectionStrings { get; set; }
        public AppSettingsConfig AppSettings { get; set; }

        public AppConfig() { }
        public static AppConfig Get()
        {
            if (Instance != null) return Instance;

            Instance = new ConfigurationBuilder()
                .AddIniFile(".\\config.ini")
                .Build()
                .Get<AppConfig>();

            return Instance;
        }
    }
}

以下のように簡単に設定内容にアクセスできる.

Program.cs
using System;

namespace ConsoleApp1
{
    class Program
    {
        static readonly AppConfig Config = AppConfig.Get();

        static void Main(string[] args)
        {
            Console.WriteLine(Config.ConnectionStrings.Database);
            Console.WriteLine(Config.AppSettings.UserName);
            Console.WriteLine(Config.AppSettings.RetryCount);
            Console.Read();
        }
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C# で WebAPI を呼び出して JSON の特定の値を出力させる

備忘録として、C# コンソールアプリで、WebAPI を呼び出し、レスポンスで得られた JSON の特定の値を取り出して出力する方法を記載します。

使用する WebAPI

今回は例として、天気予報を教えてくれる API OpenWeatherAPI を使用します。これは以下サイトで Sign Up すると無料で使用でき東京の天気予報も出力できるのでいろいろ試したいときに便利です。
参考情報 : OpenWeather
image.png
この API でフリーで使用できるものの中に今の天気を出力できる API があります。以下の様なリクエストで天気情報を得ることが来ます。

http://api.openweathermap.org/data/2.5/forecast?q=Tokyo,jp&units=metric&APPID={Your API Key}

この API で得られる JSON は以下のような形になります。

{
    "coord": {
        "lon": 139.69,
        "lat": 35.69
    },
    "weather": [
        {
            "id": 800,
            "main": "Clear",
            "description": "clear sky",
            "icon": "01n"
        }
    ],
    "base": "stations",
    "main": {
        "temp": 15.49,
        "feels_like": 10.92,
        "temp_min": 12.22,
        "temp_max": 17.78,
        "pressure": 1011,
        "humidity": 59
    },
    "visibility": 10000,
    "wind": {
        "speed": 5.7,
        "deg": 240
    },
    "clouds": {
        "all": 0
    },
    "dt": 1586359041,
    "sys": {
        "type": 1,
        "id": 8074,
        "country": "JP",
        "sunrise": 1586376987,
        "sunset": 1586423326
    },
    "timezone": 32400,
    "id": 1850144,
    "name": "Tokyo",
    "cod": 200
}

ではこの出力結果を C# で処理してみます。

C# で JSON を取り扱う

特定の値を抜き出して文字列を作成し、Console に出力するサンプルコードは以下になります。

using System;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using System.Net.Http;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Net;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            String url = "http://api.openweathermap.org/data/2.5/weather?q=Tokyo,jp&units=metric&APPID={Your API Key}";
            WebRequest request = WebRequest.Create(url);
            Stream response_stream = request.GetResponse().GetResponseStream();
            StreamReader reader = new StreamReader(response_stream);
            var obj_from_json = JObject.Parse(reader.ReadToEnd());
            var forecast_sum = obj_from_json["weather"][0]["main"];
            var forecast_des = obj_from_json["weather"][0]["description"];
            var forecast_max_temp = obj_from_json["main"]["temp_max"];
            var forecast_min_temp = obj_from_json["main"]["temp_min"];
            var forecast_hum = obj_from_json["main"]["humidity"];
            var forecast_wind = obj_from_json["wind"]["speed"];

            string forecast_output = "Tokyo is " + forecast_sum + " now. Description is " + forecast_des + ". Max tempreture is " + forecast_max_temp
                + "℃. Min tempreture is " + forecast_min_temp + "℃. Humidity is " + forecast_hum + "%. Wind is " + forecast_wind + "m/s. Have a good day!";
            Console.WriteLine(forecast_output);

        }
    }
}

出力結果は以下になります。
image.png
非常に単純なプログラムですが、JSON を扱いなれていないと以外と引っ掛かります。個人的な考えですが、WebAPI で 取得した JSON の特定の値を取り出す際は、まずは JSON 整形サイトで値のキーを確認するのが便利です。
例えば JSON 整形サイトは以下の様なものがあります。
参考情報 : JSON Pretty Linter Ver3
このサイトでは API で得られた JSON を読み込ませると、得られた値のキーを教えてくれます。例えば今回の API で得られた JSON を以下の様に貼り付けてみます。
image.png
すると、画面したの Viewer にキー付きの整形された JSON が出てきます。これは非常に便利です。
image.png
こういった JSON 整形 Website を使用すると、より分かりやすく JSON を扱うことができるのではないでしょうか。
以上、簡単な備忘録でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SwiftとC#の書き方比較

はじめに

C#を書くにあたり、「Swiftでいうと・・・これ?:expressionless:」「なんだ、これは?:innocent:」と
かなり困惑したので、比較表を作ろうと思いました。
私自身、初心者なので同じ初心者の方々のお役に立てれば嬉しいです:blush:
:triangular_flag_on_post:記事の内容に関して、勘違いもあると思いますし、これが全てではありません。
  色々な記事を読んで、自らの手をどんどん動かしてみてください!

変数と定数

Swift
//変数
var hoge: String = "Hello"
//定数
let fuga: Int = 810
C#
//変数
string hoge = "Hello";
//定数
const int fuga = 810;
  • ポイント
    • Sfiftでは型名は後 / C#では型名は前
    • C#では文末にセミコロンが必要(初めは忘れがちです:angel_tone2:
    • 右辺の型が自明である場合はわざわざ型を記載しなくても良いですが、本文では記載しておきます。

型変換(StringとIntで)

Swift
//String → Int
var hoge: String = "114"
var fuga: Int = Int(hoge)!
//Int → String
var hoge: Int = 514
var fuga: String = String(hoge)
C#
//String → Int
string hoge = "114";
int? fuga = int.Parse(hoge);
//Int → String
int hoge = 514;
string fuga = hoge.ToString();
  • ポイント
    • Swiftは 型(値)
    • C#はメソッドを使う(変換する型の組み合わせによっては他のやり方もある)

配列

Swift
//配列の作成
var someInts: [Int] = []
//要素の追加
someInts.append(1)
someInts += [2,3,4,5]
print(someInts) //[1,2,3,4,5]
C#
//要素数が可変なリストの作成
List<int> someInts = new List<int>();
//要素の追加
someInts.add(1);
//これがC#の配列宣言
int[] addInts = new int[] {2,3,4,5};
someInts.AddRange(addInts);
Console.WriteLine(someInts); //[1,2,3,4,5]
  • ポイント
    • Swiftの配列は要素数が可変
    • C#の配列は要素数が固定(Listは可変)

for文

Swift
//昇順処理なのでC#みたいに色々と書かなくてもよい
for i in 1...5 {
    print(i) //1,2,3,4,5
}
C#
//カッコ内で色々と書く
//iの開始値は1,iは5まで繰り返す,iはfor文の処理を終えるごとに+1する
for(int i = 1; i <= 5; i++)
{
    Console.WriteLine(i); //1,2,3,4,5
}

  • ポイント
    • Swiftのfor-in文は昇順処理をしてくれるため、簡潔に記載できる(Swift3.x~)
    • C#はforのカッコ内で色々と書く必要がある
    • map,foreachなど色々ありますが、今回は最も基本的なもので比較しています。

if文

Swift
var num: Int = 5
//カッコなしで書ける
if num == 5 {
    print("5だよ")
} else {
    print("5じゃないよ")
}
// 5だよ
C#
int num = 5;
//カッコがいる
if(num == 3)
{
    Console.WriteLine("3だよ");
}
else
{
    Console.WriteLine("3じゃないよ");
}
//3じゃないよ
  • ポイント
    • 書き方はそんなに違いなし!?

関数

Swift
//func 関数名(ラベル 引数名: 型) -> 戻り値の型
func plusWithNum(_ num1: Int, _ num2: Int) -> Int{
    return num1 + num2
}
//ラベルにアンスコを書くことでラベルなしで呼べる
plusWithNum(1,5)
//6

//ちょっと余談
//func 関数名(ラベル省略 引数名: 型) -> 戻り値の型
func plusWithNum(num1: Int, num2: Int) -> Int{
    return num1 + num2
}
//引数名がラベルになるが、呼び出すときに記述する必要あり
plusWithNum(num1: 1, num2: 5)
//6
C#
//戻り値の型 関数名(型 引数名)
int plusWithNum(int num1, int num2)
{
    return num1 + num2;
}
//普通に引数の型と同じものを入れたらよい
plusWithNum(1,5)
//6

//追記
// 名前付き引数での呼び出し
PlusWithNum(num1: 1, num2: 5);

// 名前付き引数の場合, 順番を前後させても問題ない
PlusWithNum(num2: 5, num1: 1);
  • ポイント
    • Swiftは「->」の後が戻り値の型で関数を使用するときに引数にはラベルが必要
    • C#は関数名の前が戻り値の型で素直に引数を入れたらよい
      • :sunny:C#もSwiftのように引数名を書いて呼び出せるようです(@Midoliy さん、ありがとうございます!)

さいごに

ざっくりと基本文法の比較を書いてみました。
これはほんの一部に過ぎません(氷山の一角ですらない:innocent:
どんどん検索をして知識を深めていきましょう(私も頑張ります)
この記事が最初の1歩を踏み出す助けになれたら幸いです。
今後はSwiftのことを中心に記事を書いていこうと思うので、よろしくお願いします:v:

参考サイト

Swift 言語ガイド
C# プログラミング ガイド

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む