.net」タグアーカイブ

Default argument and ReadLines

何を今頃なのだが C# 4.0 を調べてみた。
なんと 4.0 では関数にデフォルト引数を指定できるようになっていた。

てか、今まで無かったのかよ…

Default argument
で可能とかウソを書いてしまった、はずかしい。
引数に数の差だけのためにオーバーロードをする必要はコレで無くなるわけだ。

それと、System.IO.File.ReadLines() というイテレーション関数も追加らしい。
StreamReader.ReadLine() じゃダメなの?と思うんだが…

他は興味がわかないので今回はパス。

ということで 3.5 と 4.0 の csc.exe で試しコードを書く。

default_param.cs

using System;

class Test
{
    public static int Func(int x=5, int y=7)
    {
        return x+y;
    }
}

class __main__
{
    [STAThread]
    public static void Main(string[] args)
    {
        int n = Test.Func(y:20);
        Console.WriteLine(n);
    }
}

readlines.cs

using System;
using System.IO;

class __main__
{
    [STAThread]
    public static void Main(string[] args)
    {
        int n = 0;
        //foreach (var line in File.ReadAllLines(args[0]))
        foreach (var line in File.ReadLines(args[0]))
        {
            n++;
            Console.WriteLine("{0}: {1}", n.ToString("000"), line);
        }
    }
}

ちなみに私がパスを通しているのは 3.5 のみなのでこうなる。
うん、やっぱりどちらも 4.0 でしかビルドできないや。

これだけではツマラナイので Ubuntu でもやってみる。

あれ?デフォルト引数のほうだけ問題なくビルドできちゃった。
どっちなんだよ Ubuntu に最初から入っている mono は。

Readlines は「そんなメソッドありません」ですね、そりゃそうだ。
ReadAlllines とコメントアウトを変更すれば普通にビルドできた。
StreamReader で while ループしたほうが圧倒的効率だけどテストです。

つまり何が言いたいかというと。
コンパイルするのがメンドイけど実用無視で遊ぶなら C# は最強。
Linux で Python は単なる実用ツールでしかないもの、私はだが。

WPF4 Text Rendering

WPF 4 をコードで使う方法は前回で解ったので今回は XAML を。

System.Xaml が新たに作られたということは xmlns 名前空間が変わる?
というか System.Windows.Markup から書き換えも必要なのだろうか?

WPF から System.Xaml に移行した型

難しく説明しないでくれよ…
WPF の XAML 名前空間は以前と同じでイイということは解ったけど本当かな。

[XAML] WPF 4 を使用して、Windows 7 のジャンプ リストにカスタム タスクを追加する | 逆引きサンプル コード

上記とかでも 3.5 と同じだしイケそうだ。

後は IronPython で自分で書いた下記のようにソースコードに埋め込みしたいのだが。
IronPython で XAML

C# では Python の docstring みたく丸ごと XML とはいかない。
@”リテラル” で改行付き文字列はイケるけど ” を “” にする必要あり。

string (C#)

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

class TextReader : Window
{
	private const string TXT = @"
		<TextBlock 
		xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
		xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
	        Hello World
	   </TextBlock>";
	public TextReader()
	{
		this.Title = "XamlReader.Parse Test";
		this.Width = 400;
		this.Height = 400;
		try
		{
			var tt = XamlReader.Parse(TXT) as TextBlock;
			this.Content = tt;
			tt.Text = "こんにちは日本";
		}
		catch (Exception e)
		{
			MessageBox.Show(e.ToString());
		}
	}
}

class __main__
{
	[STAThread]
	public static void Main(string[] args)
	{
		var app = new Application();
		app.Run(new TextReader());
	}
}

これをビルドしても上手くいったけど XAML は通常 ” が多いし…
C# では別ファイルにして XamlReader.Load() のほうがいいな。

それと XAML から object を作ったら as で型を教えてあげないとメソッドが使えない。
IronPython は動的だからいらないけどコンパイルする C# では必須だね。

WPF 4.0 Text Stack Improvements – WPF Text Blog – Site Home – MSDN Blogs

とりあえずこの Text Rendering API ってのを試してみよう。
3.5 までは Windows XP での描写が変だったのがどうなるかだ。
私的にはもう XP はガン無視でいいけど、いつの OS だよ Linux 使えよ。

でも世間はそうじゃないし、しかたがないので XP に .NET 4.0 を入れる。
Windows Update に Client Profile ってのがあるんだね。

意外とサイズが小さいな、これなら仮想 OS な XP に入れてもいいや。
入れてみたら csc.exe なんかもしっかりあるのでコンパイルできると思う。

と思ったけど何このエラーは…

build した exe を持っていくと問題なく動くんだが、よくワカンネェ。
本当に XP って糞 OS だ、俺は XP で開発しないから無視しておこう。
てか Ubuntu 上の仮想マシンなので PC を行ったり来たりでメンドイ。
スクリーンショットも全部 Ubuntu から撮影してるし、関係無いか。

というわけでコード。

test.xaml

<StackPanel 
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	TextOptions.TextFormattingMode="Display">
    <TextBlock Name="block">
        クリアータイプ ... ClearType
    </TextBlock>
    <TextBlock TextOptions.TextRenderingMode="Grayscale">
        白黒 ... Grayscale
    </TextBlock>
    <TextBlock TextOptions.TextRenderingMode="Aliased">
        ぎざぎざ ... Aliased
    </TextBlock>
</StackPanel>

src.cs

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

class TextRender : Window
{
	public TextRender()
	{
		this.Title = "てきすとれんだぁ!";
		this.Width = 300;
		this.Height = 200;
		try
		{
			var fs = new FileStream("test.xaml", FileMode.Open, FileAccess.Read);
			var sp = XamlReader.Load(fs) as StackPanel;
			this.Content = sp;
			(sp.FindName("block") as TextBlock).MouseUp += on_click;
		}
		catch (Exception e)
		{
			MessageBox.Show(e.ToString());
		}
	}
	private void on_click(object sender, RoutedEventArgs e)
	{
		MessageBox.Show("くりっく");
	}
}

class __main__
{
	[STAThread]
	public static void Main(string[] args)
	{
		var app = new Application();
		app.Run(new TextRender());
	}
}

まとめて ZIP
textrender.zip

描写だけじゃ寂しいので一番上の文字列をクリックしたらメッセージを出すように。
ココも as で型指定が必要だ、やはり XAML をコンパイルするのとは扱いが違うわな。

うん、XP でも綺麗なフォント表示が可能になっている。
XP だと個々の差は解りにくいけど 7 でははっきり違いが解る。
しかし画像を並べてみると本当に XP の UI って古臭いなぁ…
今日はこのへんで。

追記

ビルドするためのバッチに

build32.bat

C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe ^
/lib:C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF ^
/reference:System.dll ^
/reference:System.Xml.dll ^
/reference:System.Xaml.dll ^
/reference:PresentationCore.dll ^
/reference:PresentationFramework.dll ^
/reference:WindowsBase.dll ^
/target:winexe ^
/out:TextReader.exe ^
/win32icon:icon.ico ^
/optimize+ ^
src.cs
PAUSE

と System.dll と System.Xml.dll への参照を追記したら XP でもビルドできた。
何で 7 と違うのよ…

Windows 7 C# Build @ .NET4.0

正月といえば、やはりプログラミングですよね。

前回は .NET Framework 3.5 の WPF を使いました。
それは Windows 7 なら最初から必ず入っているからという理由もありますが。
実は .NET 4.0 でやってみたけど上手くいかなかったから…

やはり現在の最新技術である 4.0 を使ってみたいじゃないですか。
ということで色々と自分で実験してみた。
技術文書とかは読まず(解らないもん)自力で漁った結果と前置きして。

.NET 3.5 での reference はカレント及び csc.exe のディレクトリ
それと C:\Windows\assembly を探すようだ。

このファイルに見えるものは実態ではない、端末で見れば解る。
Linux ばかり使っていて良かった、以前なら端末で見ようなんて絶対に思わない。

サブディレクトリ内に実態がある、正直なんだかよく解らない。
とにかく 4.0 の csc.exe ではこの位置の PresentationCore.dll は見つけられない。

4.0 の csc.exe があるディレクトリをよく見ると、ぶっちゃけ下記だが
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
に WPF というディレクトリがありソコにも PresentationCore.dll 等が。
ということはコッチを /lib オプションで指定すればいいようだ。

/lib 指定でビルド、System.Xaml.dll が見つからないとエラー…
って .NET 3.5 までは System.Xaml アセンブリなんて無かったような気がするんだが。
上記 assembly ディレクトリを漁ってもやはり見当たらないし。

WPF 4(VS 2010&.NET 4シリーズ) ? @IT

どうも .NET Framework 4.0 からのようで、XAML を使っていなくても必要なのね。
csc.exe のディレクトリ直下にある、ので System.Xaml.dll を参照追加指定だけ。
暗黙のリンクはやってくれない、何か事情があるのだろう。

ところで 64bit ディレクトリ指定にして配布は大丈夫なのだろうか?
exe に位置情報が埋め込まれていたりすると 32bit では動かないんだが。
32bit と 64bit の csc.exe でビルドして diff してみる。

exe 名以外は特に違いが見つからない、というかパス情報は無いみたい。
というかどちらも AnyCPU ビルドなんだからほとんど同じものが作られるんだね。
ネイティブで動くか WOW64 で動くかの違いだけなのかな?

どっちでも同じなら 32bit 位置指定のほうが心配が少なそうだから今後はそれで。
ということで 64 でないほうのディレクトリ指定でバッチを作る。

build32.bat

C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe ^
/lib:C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF ^
/reference:System.Xaml.dll ^
/reference:PresentationCore.dll ^
/reference:PresentationFramework.dll ^
/reference:WindowsBase.dll ^
/target:winexe ^
/out:TextReader.exe ^
/win32icon:icon.ico ^
/optimize+ ^
src.cs
PAUSE

v4.0.30319 というディレクトリ名は皆同じなんだろうか…
この Blog は自分で作って自分で使う(遊ぶ)人向けなのだからオケということで。

ということで今回は自分で復習のつもりでテキストリーダーを作ってみた。
UTF-8 以外は文字化けします、私は全部 UTF-8 保存しているので問題無し。
エントリポイントが解りにくいので __main__ という名前にしたw

src.cs

using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Win32;

class TextReader : Window
{
	private TextBox _textbox;

	public TextReader()
	{
		this.Title = "てきすとりぃだぁ!";
		this.Width = 400;
		this.Height = 400;
		this.CreateControls();
	}
	private void CreateControls()
	{
		_textbox = new TextBox();
		_textbox.TextWrapping = TextWrapping.NoWrap;
		_textbox.AcceptsReturn = true;
		_textbox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
		_textbox.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
		// Button
		var button = new Button();
		button.Content = "Open the Text";
		//button.Click += new RoutedEventHandler(on_button_click);
		button.Click += on_button_click;
		DockPanel.SetDock(button, Dock.Top);
		// DockPanel
		var dockpanel = new DockPanel();
		// Append
		dockpanel.Children.Add(button);
		dockpanel.Children.Add(_textbox);
		this.Content = dockpanel;
	}
	void on_button_click(object sender, RoutedEventArgs e)
	{
		var dlg = new OpenFileDialog();
		var res = dlg.ShowDialog(this);
		if (res.Value)
		{
			var sr = new StreamReader(dlg.FileName, Encoding.UTF8);
			_textbox.Text = sr.ReadToEnd();
			sr.Close();
		}
	}
}

class __main__
{
	[STAThread]
	public static void Main(string[] args)
	{
		var app = new Application();
		app.Run(new TextReader());
	}
}

textreader.zip

new RoutedEventHandler() を使わずにイベントハンドラが追加できたんだが…
以前からそうなのかな、VisualStudio だと強制的に書き込まれるはずなんだが。
余計な new が少ないのは嬉しいよ。

.NET 4.0 なので Microsoft.Win32 名前空間のダイアログも最新だ。
それ以外は 4.0 の恩恵が何も無いという…

3.0 時のような劇的進化は特に無いし 3.5 でイイやとか思ってしまうよ。
とにかく .NET 4.0 でも何もインストールせずに遊ぶ方法が解ったのでよし。

Windows 7 C# Build @ WPF

久々に Windows を使っているけど IronPython が遅すぎる。
コンパイル不要でライブラリも .NET がほぼフルで使えるので困らないし何より簡単。
なのはいいのだけれど、DLR 初期化が遅すぎて道具として使う気にならない。
地味に小物ツールを作っているんだけれど使わない…

コンパイルするなら C# で作ったほうが楽だし Web 上の Tip’s も C# なら桁違い。
それより何より Windows 7 なら何もインストールせずに C# がビルドできる。

Windows 7 の csc.exe で遊んでみる

なんか IronPython も将来性が不安な雰囲気だし。

米Microsoft、IronRubyおよびIronPythonをコミュニティに移管 – SourceForge.JP Magazine : オープンソースの話題満載

もう Windows は C# を主に利用するほうが懸命かと。
SeeMe も次で C# に戻すか考えなければ。

ということで今回は VisualStudio 等を一切使わずに WPF ウインドウを作る方法を。

VisualStudio を使ったほうが簡単だ!と言わない。
Linux ばかり使っている人間はテキストエディタとコンソールのほうが楽なんじゃい。
小物のツールを作るのに統合開発環境なんてバカな話だ。
本音は Visual C# だかの無償開発環境をインストールして何も作れない人を馬鹿にしたいから。

Microsoft.Win32.OpenFileDialog for .NET 4.0

IronPython は clr.AddReferenceByPartialName() メソッドでアセンブリ参照の追加ができた。
けど C# は同じようにコードでアセンブリ参照を追加する方法が見つからない。
というかコンパイル時に厳しい文法チェックを行う C# ではソレは無理なのかな。
素直にコンパイラオプションで参照する方法を MSDN で探す。

C# Compiler Options Listed by Category

/reference オプションを利用するだけなのか。
アイコンも /win32icon オプションだけで指定できる、VC++ より簡単だ。
引数が多くて長いのでバッチを作ったほうが楽だね。

build.bat

C:\Windows\Microsoft.NET\Framework64\v3.5\csc.exe ^
/reference:PresentationCore.dll ^
/reference:PresentationFramework.dll ^
/reference:WindowsBase.dll ^
/target:winexe ^
/out:net35wpf.exe ^
/win32icon:777.ico ^
/optimize+ ^
wpf_win.cs
PAUSE

この例は .NET 3.5 の csc.exe を使うのでフルパスを、32bit の人はパスを書き換えてね。
^ を利用すればインラインなコマンドを改行できる、bash は \ だけど。
最後に PAUSE と書けば *.bat の W クリックでコンソールが閉じないのでお勧め。
アイコンは勝手に用意して書き換えよろしく。

肝心な C# コードはせっかくなので Binding を使ってみた。
Main 関数に Single Thread Apartment 属性は必須なので忘れずに。
あ、BOM 付き UTF-8 で保存ね。

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;

class OreWin : Window
{
	private TextBox _textbox;
	private TextBlock _textblock;

	public OreWin()
	{
		this.Title = "俺のういんどう!";
		this.Width = 400;
		this.Height = 120;
		this.DataContext = _textbox;
		this.CreateControls();
		// Binding
		var binding = new Binding("Text");
		binding.Source = _textbox;
		_textblock.SetBinding(TextBlock.TextProperty, binding);
	}
	private void CreateControls()
	{
		_textbox = new TextBox();
		_textblock = new TextBlock();
		var label = new TextBlock(new Bold(new Run("何か書くと下にコピーされる")));
		var stackpanel = new StackPanel();
		// Append
		stackpanel.Children.Add(label);
		stackpanel.Children.Add(_textbox);
		stackpanel.Children.Add(_textblock);
		this.Content = stackpanel;
	}
}

class Test
{
	// WPF 等では STA 属性必須!
	[STAThread]
	public static void Main(string[] args)
	{
		var win = new OreWin();
		var app = new Application();
		app.Run(win);
	}
}
//

Pascal & C++ 屋だった頃は勘違いしやすい var に否定的だったけど…
Python 屋になった後では var と書くのすら面倒臭くなってしまった。
つーかメンバアクセスに this を書かなければ気がすまなくなっているのが怖い。
new もウザい、セミコロンを忘れる、メンバ変数も this にくっつけ…(以下略
C# って何か中途半端な気がする、まあ従うだけだが。

とにかく build.bat を W クリックしてコンパイル。
アイコンを含めたコードも置いてみる。

wpf_win_src.zip

よしよし、何もインストールしないでコンパイルできたぞと。
しかも起動はアッという間、IronPython をやっていたのが馬鹿馬鹿しい。
来年からはこんな感じで Windows でも小物を作っていきますか。

******************************

2010 年の反省、サイトもブログも更新歩度が下がり続けている。
ヤル気が無くなったわけではない、株を始めたので勉強に忙しいのです。

ちなみに今年のアフィリエイト収入は三千円ちょっと…
たった二十万円で始めた株は四ヶ月で一割強増えた…
当然のように株の更なる勉強と増資の日々に…

Linux プログラミング Blog なんてアホくさくてやってらんねぇ!
いくら Linux でのアプリ作りが主な記事の Blog だからってコレでは…

やはり Windows プログラミングをもう少し増やしたほうが良さそう。
というわけでまた来年。

Ubuntu 10.10 for DotNet EXE

こんなタイトルだけどまず Python の話。
Python で文字列を得ようとしたけど None が戻る場合がある。
今まで if で確認していたけど or 演算子が使えるようだ。

>>> import os
>>> print os.environ.get("HOME") or "Hentai"
/home/sasakima-nao
>>> print os.environ.get("LOLI")
None
>>> print os.environ.get("LOLI") or "Hentai"
Hentai

便利だけど他の言語と互換性が無いよな…
最近使っていないけど超何でもあり言語な C# なら同じ事が可能かな?
と思い久々に Ubuntu 10.10 で C# コードを書いてみたけどダメだった。

しかし何だこれは!

実行パーミッションが付いていたら exe を起動できるようになっている。
「./」指定をすると Tab キーで exe 拡張子までを保管する親切さだよ。
いつからだろう?Ubuntu 10.04 までは mono に渡す必要があったと思うんだけど。
Nautilus から W クリックすると書庫マネージャが起動してしまうんだけどw

てゆーか…
そんなに .NET アプリを Linux で使いたいのだろうか…

標準以外のライブラリは使わない、P/Invoke も WPF も利用しない。
であるならソレでもいいのだが、逆に Windows で GtkSharp なんかもご勘弁。
ところで Ubuntu 10.10 デフォルトは WindowsForm さえ使えないみたいですけど。

GtkSharp も TomBoy が残っている間は有るわけだが、今後はどうだか。
趣味プログラミングならともかくアプリケーション作りはライブラリ次第だもの。
小物を作るにも Python のほうが便利だしライブラリは標準で豊富だし、なんだよね。