20200120のC#に関する記事は9件です。

イベント メモ

EventHandlerとEventArgsについて調べたのでそれのメモ。

using System;

public class EventTest
{
    // イベントに何をするかを登録する。
    private void Start()
    {
        var sample = new EventSample();
        sample.HogeHappend += DoSomething;
    }

    // 何をするかの中身
    private void DoSomething(object sender, HogeEventArgs e)
    {
        Console.Write(e.Text);
        Console.Write(e.Num);
    }
}

// イベントを着火する側のクラス。
public class EventSample
{
    public void DoSomething()
    {
        // 引数を用意して着火();
        var e = new HogeEventArgs();
        OnEventHappend(e);
    }

    private void OnEventHappend(HogeEventArgs e)
    {
        // もしイベントがあれば実行。
        HogeHappend?.Invoke(this, e);
    }

    public event EventHandler<HogeEventArgs> HogeHappend;
}

// イベントの引数に持たせる情報。
public class HogeEventArgs : EventArgs
{
    public string Text;
    public int Num;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C# メモ 任意の3点を通る平面と2点間を通る直線、その交点を求める。

using UnityEngine;

public class StraightLine
{
    public readonly float XParamCoefficient;
    public readonly float XConstant;
    public readonly float YParamCoefficient;
    public readonly float YConstant;
    public readonly float ZParamCoefficient;
    public readonly float ZConstant;

    public StraightLine(float XParamCoefficient, float XConstant,
                        float YParamCoefficient, float YConstant,
                        float ZParamCoefficient, float ZConstant)
    {
        this.XParamCoefficient = XParamCoefficient;
        this.XConstant = XConstant;
        this.YParamCoefficient = YParamCoefficient;
        this.YConstant = YConstant;
        this.ZParamCoefficient = ZParamCoefficient;
        this.ZConstant = ZConstant;
    }

    public static StraightLine Make(Vector3 p1, Vector3 p2)
    {
        var d = p2 - p1;
        return new StraightLine(d.x, p1.x, d.y, p1.y, d.z, p1.z);
    }
}
using UnityEngine;

public sealed class Plane
{
    private readonly float p;
    private readonly float q;
    private readonly float r;

    private readonly float x0;
    private readonly float y0;
    private readonly float z0;

    private Plane(float p, float q, float r, float x0, float y0, float z0)
    {
        this.p = p;
        this.q = q;
        this.r = r;
        this.x0 = x0;
        this.y0 = y0;
        this.z0 = z0;
    }

    public static Plane Make(Vector3 a, Vector3 b, Vector3 c)
    {
        var ab = b - a;
        var ac = c - a;
        var n = new Vector3(ab.y * ac.z - ab.z * ac.y,
                            ab.z * ac.x - ab.x * ac.z,
                            ab.x * ac.y - ab.y * ac.x);

        return new Plane(n.x, n.y, n.z, a.x, a.y, a.z);
    }

    public Vector3 GetIntersection(float XParamCoefficient, float XConstant,
                                   float YParamCoefficient, float YConstant,
                                   float ZParamCoefficient, float ZConstant)
    {
        var param = (p * (x0 + XConstant) + q * (y0 + YConstant) + r * (z0 + ZConstant))
                    / (p * XParamCoefficient + q * YParamCoefficient + r * ZParamCoefficient);

        return new Vector3(XParamCoefficient * param - XConstant,
                           YParamCoefficient * param - YConstant,
                           ZParamCoefficient * param - ZConstant);
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C# メモ 任意の3点を通る平面と2点間を通る直線、その交点を求めるのに使ったのを残すためのメモ。

実際にはPlaneとRayだけでやれる。
軸が違うので変換or変数入れ替えしないといけない。
(このコードでは高さがz奥行きがy、幅がx,unityでは高さy,奥行きz,幅x向きも違う。)

using UnityEngine;

public class StraightLine
{
    public readonly float XParamCoefficient;
    public readonly float XConstant;
    public readonly float YParamCoefficient;
    public readonly float YConstant;
    public readonly float ZParamCoefficient;
    public readonly float ZConstant;

    public StraightLine(float XParamCoefficient, float XConstant,
                        float YParamCoefficient, float YConstant,
                        float ZParamCoefficient, float ZConstant)
    {
        this.XParamCoefficient = XParamCoefficient;
        this.XConstant = XConstant;
        this.YParamCoefficient = YParamCoefficient;
        this.YConstant = YConstant;
        this.ZParamCoefficient = ZParamCoefficient;
        this.ZConstant = ZConstant;
    }

    public static StraightLine Make(Vector3 p1, Vector3 p2)
    {
        var d = p2 - p1;
        return new StraightLine(d.x, p1.x, d.y, p1.y, d.z, p1.z);
    }
}
using UnityEngine;

public sealed class Plane
{
    private readonly float p;
    private readonly float q;
    private readonly float r;

    private readonly float x0;
    private readonly float y0;
    private readonly float z0;

    private Plane(float p, float q, float r, float x0, float y0, float z0)
    {
        this.p = p;
        this.q = q;
        this.r = r;
        this.x0 = x0;
        this.y0 = y0;
        this.z0 = z0;
    }

    public static Plane Make(Vector3 a, Vector3 b, Vector3 c)
    {
        var ab = b - a;
        var ac = c - a;
        var n = new Vector3(ab.y * ac.z - ab.z * ac.y,
                            ab.z * ac.x - ab.x * ac.z,
                            ab.x * ac.y - ab.y * ac.x);

        return new Plane(n.x, n.y, n.z, a.x, a.y, a.z);
    }

    public Vector3 GetIntersection(float XParamCoefficient, float XConstant,
                                   float YParamCoefficient, float YConstant,
                                   float ZParamCoefficient, float ZConstant)
    {
        var param = (p * (x0 + XConstant) + q * (y0 + YConstant) + r * (z0 + ZConstant))
                    / (p * XParamCoefficient + q * YParamCoefficient + r * ZParamCoefficient);

        return new Vector3(XParamCoefficient * param - XConstant,
                           YParamCoefficient * param - YConstant,
                           ZParamCoefficient * param - ZConstant);
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TelloをUnityでC#するときWifiでまとめたかった@EDU

EDU版だとWifiに紐付けらるようなので、やって見たメモ
やりたかったことはほぼ失敗で。。

理想的にはWifiルータで接続をまとめたかった。。

  • バッファローのWifiルータを使ってローカLANを用意(AP設定でインターネット接続)
    NoName_2019-11-13_14-53-24_No-00.png
    NoName_2019-11-13_14-52-35_No-00.png

  • TelloEDUにWifi接続を設定
    https://qiita.com/mmt/items/d2f3005d0b140679dc23

  • EDUは通信の準備OKなオレンジ点滅するが、Wifiの管理画面にはIP割当されない、、

  • Wifi管理画面から、MACアドレス入れてIP割り振りでも表示されない状態。。

  • 社用のルータにした場合はIP割り振りされて動作ができた

Wifiルータの設定が悪い OR 機器の相性が悪い が原因かも
ルータの設定を調べる時間ないので、ドングル接続を試みる

最終的にはWifiドングルで接続

ドングルでWifi直接アクセスで通信するようにしました。。

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

[WPF/xaml] 上にかぶせたTextBlockを通り抜けて下のボタンがClickイベントを取れるようにする(IsHitTestVisible)

もくじ
https://qiita.com/tera1707/items/4fda73d86eded283ec4f

やりたいこと

何かのコントロールの上にTextBlockをかぶせて文字を表示させるが、TextBlockを素通りしてその下のコントロールのClickイベントなどを受けたい。

例えば、なにかエラーメッセージを半透明のTextBlockで表示はするが、その下のコントロールではいつも通りClickイベントやらドラッグイベントやらを取りたい。
(=上にかぶせたらその部分だけ押せなくなる、というのを回避したい)

やり方

コントロールのIsHitTestVisibleをfalseにしてやる。
そうすると、そのコントロールのクリックやドラッグなどのイベントが起きなくなり、クリックしたときにはその下のコントロールのイベントが起きるようになる。
(文字だけ見えて実体がないような、幽霊な感じになる)

MainWindow.xaml
<Window x:Class="WpfApp39.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp39"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid Background="Azure">
        <!-- ボタン(押したらMsgBox出すようにButton_Clickに書いている) -->
        <Button Margin="100" Content="ボタン" Click="Button_Click" FontSize="50"/>

        <!-- IsHitTestVisibleをtrue/falseにしたTextBlock -->
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <!-- IsHitTestVisibleがtrue → あたり判定あり → 下のボタンは押せない -->
            <TextBlock Text="IsHitTestVisible = true" FontSize="50" Background="#66990099" IsHitTestVisible="True"/>
            <!-- IsHitTestVisibleがtrue → あたり判定なし → 下のボタンはを押せる -->
            <TextBlock Text="IsHitTestVisible = false" FontSize="50" Background="#66990000" IsHitTestVisible="False"/>
        </StackPanel>
    </Grid>
</Window>

上のIsHitTestVisibleをtrueにしたTextBlockはイベントをとるため、TextBlockを押してもその下のボタンを押したことにはならない。

下のIsHitTestVisibleをfalseにしたTextBlockはイベントを素通りするため、TextBlockを押すとその下のボタンをおしたことになる。

image.png

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

int.TryParseなどで、使わない out 引数のためにわざわざ変数を用意したくない!

はじめに

C#7.0 (Visual Studio 2017) 以降、_(アンダースコア)で、結果を破棄するout引数を指定できます。

サンプル(コンソールアプリ)

Program.cs
using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("整数をどうぞ:");
            var inputText1 = Console.ReadLine();
            if (!Int32.TryParse(inputText1, out _))
            {
                Console.WriteLine("整数を指定してね!");
                return;
            }

            Console.Write("日時をどうぞ:");
            dynamic inputText2 = Console.ReadLine();
            if (!DateTime.TryParse(inputText2, out DateTime _)) // CS8183:「暗黙的に型指定された破棄の型を推論できません」対策として型を指定(ここでは、out の次の DateTime)
            {
                Console.WriteLine("日時を指定してね!");
                return;
            }

            Console.WriteLine("ありがとう!");
        }
    }
}

姉妹品

out引数で用いる変数をインラインで宣言する(値も使える)コーディングとして次のようなものもあります。

sample.cs
var inputText1 = Console.ReadLine();
dynamic inputText2 = Console.ReadLine();
var valid1 = int.TryParse(inputText1 , out var intVal);
var valid2 = DateTime.TryParse(inputText2, out DateTime dtVal);
if(valid1 && valid2) {
  Console.Write("どうもありがとう {0} と {1} を入力してくれて!", intVal, dtVal);
}

参考にした資料

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

プロパティの型をそのままにReactiveProertyとして参照できるようにする

 こんな感じのプロパティがあるとします。

    public int SomeIntProperty
    {
        get;
        private set;
    }

 このプロパティを後からReactivePropertyとして参照したくなった時。
 プロパティの参照先が少なければ別にそのまま型をReactivePropertyに変えてしまってもまあいいですが、参照先が多かった場合は変更箇所も多くなり若干面倒です。
 また従来の参照箇所で、別にただのプロパティでよいはずの処理もReactivePropertyになるので、認知負荷が大きくなるかもしれません。

 以下のようにリファクタリングできます。

    // ReactivePropertyとして参照したい箇所ではこれを参照
    public IReadOnlyReactiveProperty<int> SomeIntReactiveProperty => someIntPropertyEntity;
    private readonly ReactiveProperty<int> someIntPropertyEntity = new ReactiveProperty<int>();

    public int SomeIntProperty
    {
        get => someIntPropertyEntity.Value;
        private set => someIntPropertyEntity.Value = value;
    }

 SomeIntPropertyのガワはそのままですが、中身の実態はsomeIntPropertyEntityに置き換えられています。
 そしてSomeIntReactivePropertyの実態もsomeIntPropertyEntityで共通です。
 ソースコードの通りですが、つまりSomeIntPropertyへの変更はsomeIntPropertyEntityの値の変更になり、ReactivePropertyであるsomeIntPropertyEntityの値が変更された結果SomeIntReactivePropertyとして発火することになります。

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

MERGE文が意外と遅い(C#でCSV取り込み(SQLSERVER))

MERGE

・1レコードずつMERGEを実行する…2000件で1分ほど
 ↓
・コマンドを作成後、一括して実行…2000件で45秒ほど

SELECTで存在チェック後、INSERT、UPDATE

・1レコードずつ存在チェック後、INSERT、UPDATE…2000件で1分半ほど
 ↓
・1レコードずつ存在チェック後、INSERT、UPDATEを一括実行…2000件で15秒半ほど

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

[Entity Framework] LINQ to Entities からデータベース関数を呼び出す(~EF5/EF6/EF Core)

Entity Framework では LINQ to Entities でデータ抽出ができて便利ですが、データベース関数を使いたいケースもあります。
どのような方法が用意されているか、EFバージョンごとに見ていきましょう。

Entity Framework 4/5

EF5 までの Entity Framework は .NET Framework の一部として提供され、NuGet パッケージで拡張されていました。

System.Data.Objects.EntityFunctions クラス

EntityFunctions クラスの静的メソッドを使用することで、標準的なSQL関数を呼び出すことができます。

たとえば、開始日から終了日までの日数を取得したいとき、

EntityFunctions.DiffDays(e.StartDate, e.EndDate)

のように記述すると、SQL Server であれば、

DATEDIFF (day, [Extent1].[StartDate], [Extent1].[EndDate])

のようなSQLに変換されます。

System.Data.Objects.SqlClient.SqlFunctions クラス

SQL Server 固有の組み込み関数を呼び出すことができます。
上記の日数取得は、SQL Server のみをターゲットに SqlFunctions で記述する場合、

SqlFunctions.DateDiff("day", e.StartDate, e.EndDate)

となります。

Entity Framework 6

EF6 は EntityFramework.dll を中心としたオープンソースのライブラリとして .NET Framework から独立して提供されるようになりました。

System.Data.Entity.Core.Objects.EntityFunctions クラス

EntityFunctions は System.Data.Entity.Core.Objects 空間で提供されていますが、非推奨となっています。

System.Data.Entity.DbFunctions クラス

非推奨となった EntityFunctions クラスに代わって使用できます。

DbFunctions.DiffDays(e.StartDate, e.EndDate)

と書くと

DATEDIFF (day, [Extent1].[StartDate], [Extent1].[EndDate])

のように変換されます。

System.Data.Entity.SqlServer.SqlFunctions クラス

SQL Server 向けの SqlFunctions は System.Data.Entity.SqlServer.SqlFunctions 名前空間から提供されています。

SqlQuery メソッド

SqlQuery メソッドを使うことで、生のSQLクエリを直接指定して実行することもできます。

Entity Framework Core

Microsoft.EntityFrameworkCore.DbFunctions クラス

DbFunctions クラスが使用できます。
静的クラスだった EF6 と異なり、静的プロパティ経由でインスタンスとして提供されます。

EF.Functions.DateDiffDay(e.StartDate, e.EndDate)

と書くと

DATEDIFF(DAY, [a].[StartDate], [a].[EndDate])

のように変換されます。

FromSqlRaw 拡張メソッド

FromSqlRaw 拡張メソッドを使うことで、生のSQLクエリを直接指定して実行することもできます。

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