2010年3月29日月曜日

UIパターン

UIはどうも苦手。勉強しなきゃ何だけどなぁ。
後で読むようにまとめておく。

エンジニアにもわかる「ユーザーインターフェース設計」
http://techblog.yahoo.co.jp/cat207/how_to/post_12/

ソシオメディア:UIデザインパターン
https://www.sociomedia.co.jp/category/uidesignpatterns

インフラジスティックス:Quince
http://jp.quince.infragistics.com/

あと、WPF向けのコントロールとか欲しくなるなぁ。個人では絶対無理だけど。
http://jp.infragistics.com/dotnet/netadvantage/wpf.aspx#Overview
http://www.devcomponents.com/dotnetbar-wpf/
http://www.actiprosoftware.com/Products/DotNet/WPF/WPFStudio/Default.aspx

2010年3月27日土曜日

Interfaceは参照型

Interfaceは参照型だったよな。と思い確認。

class Program
{
static void Main(string[] args)
{

Struct s = new Struct();
s.MyProperty = 1;

Interface i = s;
i.MyProperty = 2;

Interface i2 = i;
i2.MyProperty = 3;

Console.WriteLine("s :{0}", s.MyProperty);
Console.WriteLine("i :{0}", i.MyProperty);
Console.WriteLine("i2:{0}", i2.MyProperty);
}
}

interface Interface
{
int MyProperty { get; set; }
}

struct Struct : Interface
{
public int MyProperty { get; set; }
}
結果
image

正解。

つまり、Interface型に代入する際にボックス化が行われているということ。

class Program
{
static void Main(string[] args)
{
var val = new Struct();
var val2 = new Class();

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1000000000; i++)
{
object obj = val;
}
Console.WriteLine("struct -> object :" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
Interface obj = val;
}
Console.WriteLine("struct -> Interface:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
var obj = val;
}
Console.WriteLine("struct -> struct :" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
Interface obj = val2;
}
Console.WriteLine("class -> Interface:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
object obj = val2;
}
Console.WriteLine("class -> object :" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
var obj = val2;
}
Console.WriteLine("class -> class :" + sw.Elapsed);


}
}

interface Interface
{
int MyProperty { get; set; }
}

struct Struct : Interface
{
public int MyProperty { get; set; }
}


class Class : Interface
{
public int MyProperty { get; set; }
}

image

2010年3月25日木曜日

SQLite

以前のエントリで、Decimal型がDoubleに丸められてDBにInsertされることを書いた。
その後いろいろ調べた結果、フィールド型にNONEを指定していたのが原因だった。フィールド型をNONEで作成すると、NUMERICのaffinityが適用されるらしい。

http://www.sqlite.org/datatype3.html
Datatypes In SQLite Version 3 - 2.1 Determination Of Column Affinity

  1. If the declared type contains the string "INT" then it is assigned INTEGER affinity.
  2. If the declared type of the column contains any of the strings "CHAR", "CLOB", or "TEXT" then that column has TEXT affinity. Notice that the type VARCHAR contains the string "CHAR" and is thus assigned TEXT affinity.
  3. If the declared type for a column contains the string "BLOB" or if no type is specified then the column has affinity NONE.
  4. If the declared type for a column contains any of the strings "REAL", "FLOA", or "DOUB" then the column has REAL affinity.
  5. Otherwise, the affinity is NUMERIC.

つまり、NONEのaffinityを適用されるためには、フィールドをBLOB型もしくは型指定なし(NONEの指定ではない)で作成しなくてはならないようだ。NONE指定すると、その他になり5番のNUMERICが適用されるわけだ。

ちなみに、↓がテーブルを作成する際に使用したSQLiteStudioのテーブル作成画面。
カラム追加のデフォルトデータタイプがNONEになっている。
image

そして、しっかりDDLにNONEと記載される。
image
引っかかった。

その後、データタイプをBlobで作成したところ、文字列として格納されることを確認した。

2010年3月22日月曜日

boxing(ボックス化)

boxing(ボックス化)とは、値型を参照型であるobjectに変換する機能。
これにより、参照型であるobjectに値型を代入することができる。
ただし、パフォーマンス上の注意が必要。Generic型を使用することにより、boxingを防ぐことができる。

static void Main(string[] args)
{
var val = new Struct();
var val2 = new Class();

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1000000000; i++)
{
object obj = val;
}
Console.WriteLine("struct -> object:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
var obj = val;
}
Console.WriteLine("struct -> struct:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
object obj = val2;
}
Console.WriteLine("class -> object:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
var obj = val2;
}
Console.WriteLine("class -> class :" + sw.Elapsed);


var list = new List<Struct>(100000000);
var list2 = new List<Class>(100000000);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000000; i++)
{
list.Add(val);
}
Console.WriteLine("generic list <- struct:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000000; i++)
{
list2.Add(val2);
}
Console.WriteLine("generic list <- class :" + sw.Elapsed);

var list3 = new ArrayList(100000000);
var list4 = new ArrayList(100000000);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000000; i++)
{
list3.Add(val);
}
Console.WriteLine("normal list <- struct:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000000; i++)
{
list4.Add(val2);
}
Console.WriteLine("normal list <- class :" + sw.Elapsed);
}

struct Struct
{
public int MyProperty { get; set; }
}

class Class
{
public int MyProperty { get; set; }
}

image
違いは一目瞭然。

2010年3月21日日曜日

値型と参照型

EffectiveC#を読んで、基本に立ち返ってみた。

(参照渡)

class Program
{
static void Main(string[] args)
{
var val = new Class();
var val2 = val; //参照渡し

val.MyProperty = 100;

//100 が表示される
Console.WriteLine(val2.MyProperty);
}
}

class Class
{
public int MyProperty { get; set; }
}

classは参照型であり、代入は参照がコピーされる。なので、 valとVal2の指す実体は同じ。 
image

(値渡)

class Program
{
static void Main(string[] args)
{
var val = new Struct();
var val2 = val; //値渡し

val.MyProperty = 100;

//0 が表示される
Console.WriteLine(val2.MyProperty);

}
}

struct Struct
{
public int MyProperty { get; set; }
}

structは値型であり、代入はコピーが作成されるので、valを変更してもval2に影響はない。
image

2010年3月20日土曜日

本を買った


今更ながら、EffectiveC#。More~は持ってるけど一応。


@ITの記事を見てて、欲しくなりました。


Amazonに勧められました。

2010年3月19日金曜日

FriendFeed

以前のエントリで、RDBにスキーマレスなデータを格納する方法を2種類検討した。

で、2種類の方法をうまくいいとこ取りした製品があるようだ。
http://www.infoq.com/jp/news/2009/04/friendfeed-schemaless-mySQL

検索を行うカラムのみ分解しておけ、ということなのね。