C#インタラクティブで遊んでみる。

こんにちは、Takymです。
以前、以下の二つの記事を書いた事があります。(最近だけど)
C#インタラクティブを使ってみる。
C#インタラクティブを使ってみる。その2
今回も、C#インタラクティブで遊んでみたいと思います。

// 乱数
> Random rnd = new Random();
> rnd // rndの中身は?
Random { }
// ↑ 空・・・? seed値は? まあいいや・・・
> rnd.NextDouble() // 0~1の間の数字
0.72464248897723971
> rnd.Next() // 整数
301924719
// プリプロセッサの種類
> #help
キーボード ショートカット:
Enter                現在の送信が完了している場合は、評価します。完了していない場合には、新しい行を挿入します。
Ctrl-Enter           現在の送信内で、現在の送信を評価します。
前の送信内で、前の送信を現在の送信に追加します。
Shift-Enter          新しい行を挿入します。
Escape               現在の送信をクリアします。
Alt-UpArrow          現在の送信を前の送信に置き換えます。
Alt-DownArrow        現在の送信を次の送信に置き換えます (前に戻っている場合)。
Ctrl-Alt-UpArrow     現在の送信を、同じテキストで始まる前の送信に置き換えます。
Ctrl-Alt-DownArrow   現在の送信を、同じテキストで始まる次の送信に置き換えます (前に戻っている場合)。
Ctrl-K, Ctrl-Enter   対話型バッファーの最後に選択内容を貼り付け、キャレットを入力の末尾に付けます。
Ctrl-E, Ctrl-Enter   対話型バッファー内の保留中の入力の前に、選択内容を貼り付けて実行します。
Ctrl-A               最初に押すと、カーソルの置かれた送信が選択されます。もう一度押すと、ウィンドウ内のすべてのテキストが選択されます。
REPL コマンド:
#cls, #clear         編集ウィンドウの内容をクリアし、履歴と実行コンテキストはそのまま保持します。
#help                指定のコマンド、または指定していない場合には利用可能なすべてのコマンドとキー バイデンィングに関する、ヘルプを表示します。
#reset               実行環境を初期状態にリセットし、履歴を保持します。
スクリプト ディレクティブ:
#r                   指定されたアセンブリとそのすべての依存関係へのメタデータ参照を追加します (例: #r "myLib.dll")。
#load                指定されたスクリプト ファイルを読み込んで実行します (例: #load "myScript.csx")。
// コマンドプロンプト起動
> Process.Start("cmd.exe");
// ↑新しいウィンドウで開かれました。
// ちょっと残念・・・。

今回はここまでです。
最後まで読んでくれてありがとうございました。

C#を1.0~7.0までのバージョンを比較してみる。その2

こんにちは、Takymです。
今回は前回のC#を1.0~7.0までのバージョンを比較してみる。その1続きです。

C# 1.0 vs C# 2.0

前回、書くことができなかった部分を紹介します。

Partial Type

これは、クラスを複数のファイルに分割して書くことができる機能です。

partial class Test
{
public Test()
{
SayHello();
}
}
partial class Test
{
public void SayHello()
{
Console.WriteLine("hello");
}
}

この機能はC# 1.0で使用する事ができません。

Nullable型

これは、構造体の型名の後ろに?を付けてnull値を使用できるようにするものです。
(この機能、昔からあったのか。意外だなぁ)

int? a = null;

しかし、C# 1.0でこの機能を使用したい場合は、以下の様に必ずクラスを作成しなければなりません。

public class NullableInt32
{
public int Value;
}

それ以外にも新機能はありますがここでは割愛します。

C# 2.0 vs C# 3.0

今度は、C# 2.0とC# 3.0を比べてみたいと思います。

暗黙的型付け

以下の様にvarを使用すると、コンパイラが型を判断してくれます。

var num = 123;
var str = "Test";
var bol = true;
var flo = 1.5F;

この機能は、C# 1.0、C# 2.0では使用できません。

拡張メソッド

静的メソッドの最初の引数にthisを付けると、あたかもインスタンスメソッドの様に使用する事ができます。

public static class StringExtensions
{
public static string AddString(this string left, string right)
{
return left + right;
}
// 別にAddStringと同じクラスにする必要はない。
public static void Main()
{
string str = "abc";
// C# 1.0、C# 2.0の場合
string str2 = StringExtensions.AddStriong(str, "def");
// C# 3.0以降の場合
string str3 = str.AddStriong("def");
}
}

ラムダ式

これは、匿名メソッドの進化版みたいなものです。
C# 2.0では以下の様に記述しなければいけませんでした。

Func f = delegate(string str)
{
return str.Replace("abc", "123");
};
Console.WriteLine(f("abcdef")); // 出力:123def

しかし、C# 3.0では以下の様に記述する事ができます。

Func f = (string str) =>
{
return str.Replace("abc", "123");
};
Console.WriteLine(f("abcdef")); // 出力:123def

とりあえず、今回はここまでです。
最後まで読んでくれてありがとうございました。
分からない事、間違い等はこの記事にコメントしてください。
参考にしたページ①:C# 2.0 の新機能 – C# によるプログラミング入門 | ++C++; // 未確認飛行 C
参考にしたページ②:C# 3.0 の新機能 – C# によるプログラミング入門 | ++C++; // 未確認飛行 C

続きを読む “C#を1.0~7.0までのバージョンを比較してみる。その2”

C#を1.0~7.0までのバージョンを比較してみる。その1

こんにちは、Takymです。
C# 1.0C# 7.0を比較したいと思いました。
何故、そんな事をしようと思ったのかというと、C# 1.0からC# 7.0までどのくらい進化したか調べたいと思ったからです。

C# 1.0 vs C# 2.0

いきなりC# 7.0とC# 1.0を比較するのは大変なので、とりあえず今回は、C# 2.0を比較したいと思います。
また、全ての機能は比較しません。

ジェネリック

public class Test<T>
{
T[] Items;
public T GetValue(int index)
{
return this.Items[index];
}
}

C# 1.0では、ジェネリックを使用する事ができません。

匿名メソッド

public delegate Function();
static void Main(string[] args)
{
Function func = delegate {
for (int i = 0; i < args.Length; ++i) {
Console.WriteLine("args[{0}]:{1}", i, args[i]);
}
};
func();
}

これも、C# 1.0では使用できません。
C# 1.0でもデリゲートは使用できます。

イテレーター

public IEnumerator GetEnumerator()
{
for (int i = 0; i < 10; ++i) {
yield return "HogeHoge";
}
}
public IEnumerator GetEnumerator()
{
ArrayList result = new ArrayList(10);
for (int i = 0; i < 10; ++i) {
result.Add("HogeHoge");
}
return result;
}

これ以外にも違いはあるようです。
今回は、ここまでです。
最後まで読んでくれてありがとうございました。
分からない事、間違い等はこの記事にコメントしてください。
参考にしたページ:C# 2.0 の新機能 – C# によるプログラミング入門 | ++C++; // 未確認飛行 C

続きを読む “C#を1.0~7.0までのバージョンを比較してみる。その1”

C#インタラクティブを使ってみる。その2

こんにちは、Takymです。
今回は、またC#インタラクティブで遊ぼうかなと思います。
前回→http://takymsystems.blog.fc2.com/blog-entry-5.html
また、これからC#インタラクティブを使った記事を時々更新したいなと思います。(シリーズ化したいです。)

さっそくC#インタラクティブを使う

// 1. コンソールのタイトルを変えてみる。
> Console.Title = "てすと";
// ↑何も起こらない..........
// 2. ウィンドウを表示してみる。
> #r "System.Windows.Forms.dll" // まず、System.Windows.Forms.dllの参照を追加。
> using System.Windows.Forms;   // C#インタラクティブでもusingは必要らしい。
> MessageBox.Show("hello");
// 以下の様に表示されました。

// 3. Formクラスを継承したクラスを作ってみる。
> class Form1 : Form {
. 	public Form1() {
. 		Button btn = new Button();
. 		btn.Text = "btn";
. 		btn.Location = new System.Drawing.Point(50, 50);
. 		this.Controls.Add(btn);
. 	}
. }
> Application.Run(new Form1()); // 実行と思ったら・・・
単一スレッド上で 2 回目のメッセージ ループを開始することは有効な操作ではありません。Form.ShowDialog を使用してください。
+ System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int, System.Windows.Forms.ApplicationContext)
+ System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int, System.Windows.Forms.ApplicationContext)
+ System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
// ↑無理らしいです。
> new Form1().ShowDialog()
Cancel // 普通に実行して終了するとCancelが返される事は初めて知りました。(恥ずかしい・・・)
// ↓動作写真



今回はここまでにします。
最後まで読んでくれてありがとうございました。

はてなから移転してきました。

Hatena Blog からの記事の移転が完了した – takym.code.blog
こんにちは、Takymです。
実は、今更ですが前まではてなブログを利用してブログを書いていました。
URL→http://takym-program.hateblo.jp/
それで、FC2でブログを始めて少しテスト(?)して、使いやすかったので、正式にこっちでブログを更新します。
(因みに、はてなの方ではあまり更新していませんでした。)
はてなで書いた記事はそのままにしておきます。
変更が必要になった時は、リメイク版としてFC2の方に上げます。

C# 7.0 でタプル(ValueTuple)を自作してみる。

こんにちは、Takymです。
今回は、System.VslueTupleをNuGetからダウンロードせずに、自分で実装しようと思います。

目次

メリット・デメリット

メリット

  • 好きな機能を実現できる。
  • System.VslueTupleの仕組みが分かる。
  • 外部参照じゃないから高速。(ライブラリにしたら意味がない)

デメリット

  • 関数が多くて実装がめんどくさい。
  • 公式じゃないから、バグが出る可能性がある。

ValueTupleの実装

MSDNに載っていました。
https://msdn.microsoft.com/ja-jp/library/system.valuetuple(v=vs.110).aspx

とりあえず実装

まず最初に以下の様に実装してみました。
ソースコードをスキップする。

namespace System
{
public class ValueTuple
{
public int FieldCount { get; protected set; }
public ValueTuple()
{
FieldCount = 0;
}
public override bool Equals(object obj)
{
ValueTuple v = obj as ValueTuple;
if (v == null) {
return false;
}
return this.FieldCount == v.FieldCount;
}
public override int GetHashCode()
{
return 0;
}
public override string ToString()
{
return "{ \"FieldCount\":0 }";
}
public static bool operator ==(ValueTuple left, ValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple left, ValueTuple right)
{
return !left.Equals(right);
}
}
public class ValueTuple<T1> : ValueTuple
{
public T1 Item1;
public ValueTuple()
{
this.FieldCount = 1;
}
public ValueTuple(T1 item1)
{
this.FieldCount = 1;
this.Item1 = item1;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1>) {
ValueTuple<T1> v = ((ValueTuple<T1>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\" }}";
}
public void Deconstruct(out T1 item1)
{
item1 = this.Item1;
}
}
public class ValueTuple<T1, T2> : ValueTuple
{
public T1 Item1;
public T2 Item2;
public ValueTuple()
{
this.FieldCount = 2;
}
public ValueTuple(T1 item1, T2 item2)
{
this.FieldCount = 2;
this.Item1 = item1;
this.Item2 = item2;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2>) {
ValueTuple<T1, T2> v = ((ValueTuple<T1, T2>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2)
{
item1 = this.Item1;
item2 = this.Item2;
}
}
public class ValueTuple<T1, T2, T3> : ValueTuple
{
public T1 Item1;
public T2 Item2;
public T3 Item3;
public ValueTuple()
{
this.FieldCount = 3;
}
public ValueTuple(T1 item1, T2 item2, T3 item3)
{
this.FieldCount = 3;
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3>) {
ValueTuple<T1, T2, T3> v = ((ValueTuple<T1, T2, T3>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
}
}
public class ValueTuple<T1, T2, T3, T4> : ValueTuple
{
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public ValueTuple()
{
this.FieldCount = 4;
}
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4)
{
this.FieldCount = 4;
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4>) {
ValueTuple<T1, T2, T3, T4> v = ((ValueTuple<T1, T2, T3, T4>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3, out T4 item4)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
}
}
public class ValueTuple<T1, T2, T3, T4, T5> : ValueTuple
{
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public T5 Item5;
public ValueTuple()
{
this.FieldCount = 5;
}
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
{
this.FieldCount = 5;
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
this.Item5 = item5;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4, T5>) {
ValueTuple<T1, T2, T3, T4, T5> v = ((ValueTuple<T1, T2, T3, T4, T5>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4)
&& this.Item5.Equals(v.Item5);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode()
^ this.Item5.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\", \"Item5\":\"{this.Item5}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
item5 = this.Item5;
}
}
public class ValueTuple<T1, T2, T3, T4, T5, T6> : ValueTuple
{
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public T5 Item5;
public T6 Item6;
public ValueTuple()
{
this.FieldCount = 6;
}
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
{
this.FieldCount = 6;
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
this.Item5 = item5;
this.Item6 = item6;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4, T5, T6>) {
ValueTuple<T1, T2, T3, T4, T5, T6> v = ((ValueTuple<T1, T2, T3, T4, T5, T6>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4)
&& this.Item5.Equals(v.Item5)
&& this.Item6.Equals(v.Item6);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode()
^ this.Item5.GetHashCode() ^ this.Item6.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\", \"Item5\":\"{this.Item5}\", " +
$"\"Item6\":\"{this.Item6}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
item5 = this.Item5;
item6 = this.Item6;
}
}
public class ValueTuple<T1, T2, T3, T4, T5, T6, T7> : ValueTuple
{
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public T5 Item5;
public T6 Item6;
public T7 Item7;
public ValueTuple()
{
this.FieldCount = 7;
}
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
{
this.FieldCount = 7;
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
this.Item5 = item5;
this.Item6 = item6;
this.Item7 = item7;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7>) {
ValueTuple<T1, T2, T3, T4, T5, T6, T7> v = ((ValueTuple<T1, T2, T3, T4, T5, T6, T7>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4)
&& this.Item5.Equals(v.Item5)
&& this.Item6.Equals(v.Item6)
&& this.Item7.Equals(v.Item7);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode()
^ this.Item5.GetHashCode() ^ this.Item6.GetHashCode() ^ this.Item7.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\", \"Item5\":\"{this.Item5}\", " +
$"\"Item6\":\"{this.Item6}\", \"Item7\":\"{this.Item7}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
item5 = this.Item5;
item6 = this.Item6;
item7 = this.Item7;
}
}
public class ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn> : ValueTuple where Tn: ValueTuple, new()
{
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public T5 Item5;
public T6 Item6;
public T7 Item7;
public Tn ItemN;
public ValueTuple()
{
this.FieldCount = 7 + new Tn().FieldCount;
}
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, Tn itemN)
{
this.FieldCount = 7;
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
this.Item5 = item5;
this.Item6 = item6;
this.Item7 = item7;
this.ItemN = itemN;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn>) {
ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn> v = ((ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4)
&& this.Item5.Equals(v.Item5)
&& this.Item6.Equals(v.Item6)
&& this.Item7.Equals(v.Item7)
&& this.ItemN.Equals(v.ItemN);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode()
^ this.Item5.GetHashCode() ^ this.Item6.GetHashCode() ^ this.Item7.GetHashCode() ^ this.ItemN.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\", \"Item5\":\"{this.Item5}\", " +
$"\"Item6\":\"{this.Item6}\", \"Item7\":\"{this.Item7}\", \"ItemN\":{this.ItemN} }}";
}
public void Deconstruct(
out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out Tn itemN)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
item5 = this.Item5;
item6 = this.Item6;
item7 = this.Item7;
itemN = this.ItemN;
}
}
}


しかし、コンパイルに失敗しました。
どうやら、ValueTupleは構造体でなければいけないようです。
因みに、FieldCountはタプルのフィールドの数です。
Equalsメソッドで、タプルの値が同じかどうか、計算できるようにしています。
GetHashCodeメソッドはEqualsメソッドの為に実装しています。
戻り値はアイテムの値から作成するようにしています。
ToStringメソッドはアイテムの値をJSON形式にしています。これは僕の趣味です。
(※JSONをタプルに変換するコードは含まれていません。)
Deconstructメソッドはタプルを分解するためのメソッドです。
ValueTupleは、アイテムが1個の時のタプルです。
一個増えるにつれて、Itemを一つずつ増やしています。
ValueTupleは、アイテムが8個以上の時のタプルです。
TnはValueTuple型を継承した型のみ使用できます。
つまり、Tnに別のValueTupleを含む事ができます。
なので、理論上無限のタプルを生成する事ができます。
Createメソッドが無いのは手抜きです。

正しい実装

classの部分をstructに変えて少し修正しました。
ソースコードをスキップする。

namespace System
{
public interface IValueTuple
{
int FieldCount { get; }
}
public struct ValueTuple : IValueTuple
{
public int FieldCount
{
get
{
return 0;
}
}
public override bool Equals(object obj)
{
if (obj == null) {
return false;
}
if (obj is ValueTuple) {
ValueTuple v = ((ValueTuple)(obj));
return this.FieldCount == v.FieldCount;
} else {
return false;
}
}
public override int GetHashCode()
{
return 0;
}
public override string ToString()
{
return "{ \"FieldCount\":0 }";
}
public static bool operator ==(ValueTuple left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple left, IValueTuple right)
{
return !left.Equals(right);
}
}
public struct ValueTuple<T1> : IValueTuple
{
public int FieldCount
{
get
{
return 1;
}
}
public T1 Item1;
public ValueTuple(T1 item1)
{
this.Item1 = item1;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1>) {
ValueTuple<T1> v = ((ValueTuple<T1>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\" }}";
}
public void Deconstruct(out T1 item1)
{
item1 = this.Item1;
}
public static bool operator ==(ValueTuple<T1> left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple<T1> left, IValueTuple right)
{
return !left.Equals(right);
}
}
public struct ValueTuple<T1, T2> : IValueTuple
{
public int FieldCount
{
get
{
return 2;
}
}
public T1 Item1;
public T2 Item2;
public ValueTuple(T1 item1, T2 item2)
{
this.Item1 = item1;
this.Item2 = item2;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2>) {
ValueTuple<T1, T2> v = ((ValueTuple<T1, T2>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2)
{
item1 = this.Item1;
item2 = this.Item2;
}
public static bool operator ==(ValueTuple<T1, T2> left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple<T1, T2> left, IValueTuple right)
{
return !left.Equals(right);
}
}
public struct ValueTuple<T1, T2, T3> : IValueTuple
{
public int FieldCount
{
get
{
return 3;
}
}
public T1 Item1;
public T2 Item2;
public T3 Item3;
public ValueTuple(T1 item1, T2 item2, T3 item3)
{
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3>) {
ValueTuple<T1, T2, T3> v = ((ValueTuple<T1, T2, T3>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
}
public static bool operator ==(ValueTuple<T1, T2, T3> left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple<T1, T2, T3> left, IValueTuple right)
{
return !left.Equals(right);
}
}
public struct ValueTuple<T1, T2, T3, T4> : IValueTuple
{
public int FieldCount
{
get
{
return 4;
}
}
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4)
{
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4>) {
ValueTuple<T1, T2, T3, T4> v = ((ValueTuple<T1, T2, T3, T4>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3, out T4 item4)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
}
public static bool operator ==(ValueTuple<T1, T2, T3, T4> left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple<T1, T2, T3, T4> left, IValueTuple right)
{
return !left.Equals(right);
}
}
public struct ValueTuple<T1, T2, T3, T4, T5> : IValueTuple
{
public int FieldCount
{
get
{
return 5;
}
}
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public T5 Item5;
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
{
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
this.Item5 = item5;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4, T5>) {
ValueTuple<T1, T2, T3, T4, T5> v = ((ValueTuple<T1, T2, T3, T4, T5>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4)
&& this.Item5.Equals(v.Item5);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode()
^ this.Item5.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\", \"Item5\":\"{this.Item5}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
item5 = this.Item5;
}
public static bool operator ==(ValueTuple<T1, T2, T3, T4, T5> left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple<T1, T2, T3, T4, T5> left, IValueTuple right)
{
return !left.Equals(right);
}
}
public struct ValueTuple<T1, T2, T3, T4, T5, T6> : IValueTuple
{
public int FieldCount
{
get
{
return 6;
}
}
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public T5 Item5;
public T6 Item6;
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
{
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
this.Item5 = item5;
this.Item6 = item6;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4, T5, T6>) {
ValueTuple<T1, T2, T3, T4, T5, T6> v = ((ValueTuple<T1, T2, T3, T4, T5, T6>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4)
&& this.Item5.Equals(v.Item5)
&& this.Item6.Equals(v.Item6);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode()
^ this.Item5.GetHashCode() ^ this.Item6.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\", \"Item5\":\"{this.Item5}\", " +
$"\"Item6\":\"{this.Item6}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
item5 = this.Item5;
item6 = this.Item6;
}
public static bool operator ==(ValueTuple<T1, T2, T3, T4, T5, T6> left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple<T1, T2, T3, T4, T5, T6> left, IValueTuple right)
{
return !left.Equals(right);
}
}
public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7> : IValueTuple
{
public int FieldCount
{
get
{
return 7;
}
}
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public T5 Item5;
public T6 Item6;
public T7 Item7;
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
{
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
this.Item5 = item5;
this.Item6 = item6;
this.Item7 = item7;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7>) {
ValueTuple<T1, T2, T3, T4, T5, T6, T7> v = ((ValueTuple<T1, T2, T3, T4, T5, T6, T7>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4)
&& this.Item5.Equals(v.Item5)
&& this.Item6.Equals(v.Item6)
&& this.Item7.Equals(v.Item7);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode()
^ this.Item5.GetHashCode() ^ this.Item6.GetHashCode() ^ this.Item7.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\", \"Item5\":\"{this.Item5}\", " +
$"\"Item6\":\"{this.Item6}\", \"Item7\":\"{this.Item7}\" }}";
}
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
item5 = this.Item5;
item6 = this.Item6;
item7 = this.Item7;
}
public static bool operator ==(ValueTuple<T1, T2, T3, T4, T5, T6, T7> left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple<T1, T2, T3, T4, T5, T6, T7> left, IValueTuple right)
{
return !left.Equals(right);
}
}
public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn> : IValueTuple where Tn: IValueTuple, new()
{
public int FieldCount
{
get
{
return 7 + ItemN.FieldCount;
}
}
public T1 Item1;
public T2 Item2;
public T3 Item3;
public T4 Item4;
public T5 Item5;
public T6 Item6;
public T7 Item7;
public Tn ItemN;
public Tn Rest
{
get
{
return this.ItemN;
}
set
{
this.ItemN = value;
}
}
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, Tn itemN)
{
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
this.Item5 = item5;
this.Item6 = item6;
this.Item7 = item7;
this.ItemN = itemN;
}
public override bool Equals(object obj)
{
if (obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn>) {
ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn> v = ((ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn>)(obj));
if (this.FieldCount == v.FieldCount) {
return this.Item1.Equals(v.Item1)
&& this.Item2.Equals(v.Item2)
&& this.Item3.Equals(v.Item3)
&& this.Item4.Equals(v.Item4)
&& this.Item5.Equals(v.Item5)
&& this.Item6.Equals(v.Item6)
&& this.Item7.Equals(v.Item7)
&& this.ItemN.Equals(v.ItemN);
} else {
return false;
}
} else {
return false;
}
}
public override int GetHashCode()
{
return this.Item1.GetHashCode() ^ this.Item2.GetHashCode() ^ this.Item3.GetHashCode() ^ this.Item4.GetHashCode()
^ this.Item5.GetHashCode() ^ this.Item6.GetHashCode() ^ this.Item7.GetHashCode() ^ this.ItemN.GetHashCode();
}
public override string ToString()
{
return $"{{ \"FieldCount\":{this.FieldCount}, \"Item1\":\"{this.Item1}\", \"Item2\":\"{this.Item2}\", " +
$"\"Item3\":\"{this.Item3}\", \"Item4\":\"{this.Item4}\", \"Item5\":\"{this.Item5}\", " +
$"\"Item6\":\"{this.Item6}\", \"Item7\":\"{this.Item7}\", \"ItemN\":{this.ItemN} }}";
}
public void Deconstruct(
out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out Tn itemN)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
item5 = this.Item5;
item6 = this.Item6;
item7 = this.Item7;
itemN = this.ItemN;
}
public static bool operator ==(ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn> left, IValueTuple right)
{
return left.Equals(right);
}
public static bool operator !=(ValueTuple<T1, T2, T3, T4, T5, T6, T7, Tn> left, IValueTuple right)
{
return !left.Equals(right);
}
}
}


構造体はクラスを継承する事ができないので、インターフェースを使う事にしました。
また、公式の実装を見ると、ItemNはRestになっているようなので、プロパティでItemNを参照できるようにしました。

使用例

以下のプログラムを実行してみます。

using System;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("{0}",
("string",      123,             true,              1.5,
"hogehoge",    new object(),    new DateTime(),    "test",
false,         0,               3.2,               987,
"ABC123",      "a1b2"));
Console.ReadLine();
}
}
}

実行したら、以下の様な表示になる筈です。

{
"FieldCount":14,
"Item1":"string",
"Item2":"123",
"Item3":"True",
"Item4":"1.5",
"Item5":"hogehoge",
"Item6":"System.Object",
"Item7":"0001/01/01 00:00:00",
"ItemN":{
"FieldCount":7,
"Item1":"test",
"Item2":"False",
"Item3":"0",
"Item4":"3.2",
"Item5":"987",
"Item6":"ABC123",
"Item7":"a1b2"
}
}

(※読みやすく整形されています。)

感想

実装が多いので大変でした。
自分で実装したValueTupleのToStringメソッドが正しく実行できた時は嬉しかったです。
分からない事はこの記事のコメントで聞いてください。
間違えもこの記事のコメントで指摘してくれると、嬉しいです。
最後まで読んでくれてありがとうございます。

C#インタラクティブを使ってみる。

こんにちは、Takymです。
今回は、C#インタラクティブを使って色々実験したいと思います。

C#インタラクティブとは?

C#のソースコードを対話形式で実行できるツールです。
Visual Studioなら、表示→その他ウィンドウ→C# Interactiveから開く事ができます。

色々試してみる。

// 1. コマンドライン引数
> Environment.GetCommandLineArgs() // ;を付けないで実行すると、値がそのまま表示されます。
string[4] { "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\ManagedLanguages\\VBCSharp\\InteractiveComponents\\InteractiveHost.exe", "InteractiveHostChannel-e0a96bd0-7de6-4846-9c6d-31d9f84a1659", "InteractiveHostSemaphore-19d606fe-b259-4388-ae75-09a294e97107", "4024" }
// ↑長い...
// 2.作業ディレクトリ
> Environment.CurrentDirectory
"C:\\Users\\XXXXXX"
// ↑ユーザーディレクトリが設定されているようです。
// 3. 例外
> throw null; // NullReferenceException
オブジェクト参照がオブジェクト インスタンスに設定されていません。
// ↑メッセージの部分だけが表示されます。
// 4. 関数
> string Test() {
.     Console.WriteLine("hello");
.     return "test";
. }
> Test() // ← ;を付けないでみる。
hello
"test"
// Console.WriteLine等で標準出力に出力したら普通に表示されて、
// returnしたら、ダブルクオート(")が付加される(値をそのまま表示)ようです。

短いですが、今回は以上です。
読んでくださってありがとうございます。

Visual Studio 2017でアカウントが紐付けできなくなった場合の対処法

こんにちは、Takymです。
この前、Visual Studio 2017(以下、VS2017)でアカウントを紐付けする際に以下の様なエラーが出ました。

英語だらけで意味がわかりませんでした。
一度、VS2017を再インストールしましたが、解決しませんでした。その後、ネットで色々調べました。
そして、レジストリキーの‘HKEY_CURRENT_USER\SOFTWARE\Microsoft\VSCommon\ConnectedUser’を削除したら紐付けできるようになりました。

解決手順

  1. Win+Rを押して、ファイル名を指定して実行を開きます。
  2. ファイル名の所に’regedit.exe’を入力してOKボタンを押します。
  3. UACを許可します。(※必ず許可してください。)
  4. 一応、バックアップをとります。
  5. ‘HKEY_CURRENT_USER\SOFTWARE\Microsoft\VSCommon\ConnectedUser’を削除します。


この方法で解決できました。
引用元→https://teratail.com/questions/71925
(というか、僕が質問した。)

これからブログを始めます。初投稿です。

はじめまして、こんにちは!
Takym(たかやまと読みます)です。
今回からFC2を使用して、ブログを始めたいと思います。
どうぞよろしくお願いします。
このブログでは主にプログラミングやパソコンの事等を書く予定です。
僕が使用できる言語はC#、HTML/CSS/JavaScriptくらいです。
その中でも得意な言語はC#です。
今はC言語を習得中です。
好きなものはパソコンとプログラミングとゲームです。
好きなゲームはSteins;Gate(シュタゲ)とMinecraft(マイクラ)です。
このブログは不定期に更新します。
一ヶ月に2、3回は更新したいです。
これから、よろしくお願いします。

ポインタを使った値型の参照渡し

FC2Hatenaに投稿した記事の写しです。


前回は、ポインタを使ってメモリにアクセスできるので、暗黙的に型を別の型に変換できるのではないかと思いましたのでC#で試してみました。今回は、ポインタを使って値型の参照渡しをしてみたいと思います。
(※ポインタを使うには ‘/unsafe’ でコンパイルする必要があります。)

using System;

namespace MemoryTest
{
    // ポインタにするためアンセーフにする。
    static unsafe class Program
    {
        static void Main(string[] args)
        {
            // ポインタを使う変数。
            Target tc = new Target();
            tc.number = 0x12345678;

            // 変更前の値を表示。
            Console.WriteLine("number=0x{0:X}", tc.number);

            // 値を変更する関数呼び出し。
            Test(&tc);

            // 変更後の値を表示。
            Console.WriteLine("number=0x{0:X}", tc.number);
        }

        static void Test(Target* pointer)
        {
            // 値を変更。
            pointer->number = 0x9ABCDEF0;
        }

        // ターゲットの型。
        // 値型でなければいけない。(フィールドも。)
        struct Target
        {
            public uint number;
        }
    }
}

感想

これは、ポインタを使わずにoutキーワードを使えば簡単に同じことをできると思いました。

ソースコードのダウンロード

MemoryTest.2015-4-15.zip

WordPress.com で次のようなサイトをデザイン
始めてみよう