ATOK2008 for Mac 7月発売

発売日:2008年7月18日(金) Just MyShop予約開始日:2008年6月24日(火)

ATOK 2008 for Macは最新のMac OS X v10.5 Leopardに、より最適化し、スピード、快適さ、安心を追求しました。

さらにATOK 2008 for Windowsで話題になった新機能や、Macでは新登場の「ATOKダイレクト」を搭載し、変換精度がさらに進化しています。

日本語入力の新しいスタンダードになる、ATOK 2008 for Macで快適な入力環境を。

日本語入力システム ATOK 2008 for Mac

買ったばっかなのに・・・。

Share

カスタムコントロールのプロパティの型をコントロールにしたい時に必要なTypeConverterの実装

以前に、.NET Framework1.1を利用している時に下記のエントリをしました。

カスタムコントロールのプロパティの型をコントロールにしたい時に必要なTypeConverterの抽象クラスです。

各、コントロール毎にTypeConverterを一から作るのはめんどくさいので、抽象クラスを作っておいて、継承先で型を指定するプロパティをオーバライドする事で指定の型のTypeConverterを作成しています。

バージョンは1.1:カスタムコントロールのプロパティの型をコントロールにしたい時に必要なTypeConverterの抽象クラス – NAL-6295の舌先三寸

今回、ジェネリックを利用する事で、抽象クラスである必要が無くなり、継承する必要がなくなりました。

利用するときに、その型を指定すればよいだけです。

using System;
using System.Drawing;
using System.Reflection;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
namespace NAL6295.Web.UI.Controls
{
/// <summary>
/// コントロールの型情報と型名の相互変換
/// </summary>
/// <typeparam name="T">System.Web.UI.Controlを継承したクラスのみ指定可能</typeparam>
public class ControlConverter<T> : System.ComponentModel.StringConverter where T:System.Web.UI.Control    {
private ArrayList _values;
/// <summary>
///		値リストのサポートを許可する
/// </summary>
/// <param name="context"></param>
/// <returns></returns>		
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}
/// <summary>
///		値リストの作成
/// </summary>
/// <param name="context"></param>
/// <returns>デザイン画面に存在するControlTypeプロパティで指定されたコントロールのリストを取得しそのIDリストを返す</returns>
public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
_values = new ArrayList();
foreach (System.Web.UI.Control item in GetControlList(context))
{
_values.Add(item.ID);
}
return new System.ComponentModel.TypeConverter.StandardValuesCollection(_values);
}
/// <summary>
///		文字列型から指定された型への変換
///		選択リストに無い文字列が指定されていたときは、String.Emptyを返す
/// </summary>
/// <param name="context"></param>
/// <param name="culture"></param>
/// <param name="value"></param>
/// <returns></returns>
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
foreach (System.Web.UI.Control item in GetControlList(context))
{
if (item.ID == (string)value)
{
return base.ConvertFrom(context, culture, value);
}
}
return string.Empty;
}
return base.ConvertFrom(context, culture, value);
}
/// <summary>
///		指定された型のリストを返す
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private object[] GetControlList(ITypeDescriptorContext context)
{
IReferenceService serv = (IReferenceService)context.GetService(typeof(IReferenceService));
return serv.GetReferences(typeof(T));
}
}
}

利用例:

public class カスタムコントロール : Control
{
//いろんな処理
private _hintControlName = "";
[TypeConverter(typeof(ControlConverter<Label>))
,DefaultValue("")
,Description("このコントロールのヒントを表示するラベルを選択するプロパティです。")]
public string Hint
{
get
{
return _hintControlName;
}
set
{
_hintControlName = value;
}
}
//いろんな処理
}
Share

全員負け組

負け組だと思っている人も、勝ち組だと思っている人も、その枠組みにいる間は、全員負け組である。

Share

超今更な話だけどGenericの型パラメータの制約は便利だ

最近、Genericを利用したクラスを作成する機会があった。

もともと、以下のような感じのGenericを利用していないクラスがあったのをGenericに対応した。

public abstract class ほにゃAbstract
{
public ほにゃAbstract()
{
}
public abstract DataTable TableData
{get;}
}
public class ふが :ほにゃabstract
{
private 型のついたテーブル型 _data = new 型のついたテーブル型();
public override DataTable TableData
{
get
{
return _data;
}
}
}

というクラスがあったとして、Dataプロパティを利用するときは、常にDataTable型なので、型付DataSetで定義したテーブルを返す時は

ふが ふがインスタンス = インスタンス作成();
型のついたテーブル型 データ = (型のついたテーブル型)ふがインスタンス.TableData;

といった感じにいちいちキャストする必要があったが

public abstract class ほにゃAbstract<T> where T:DataTable,new()
{
public abstract ほにゃAbstract()
{
}
private T _data = new T();
public abstract T TableData
{
get
{
return _data;
}
}
}
public class ふが :ほにゃabstract<型のついたテーブル型>
{
}

とすることで、

ふが ふがインスタンス = インスタンス作成();
型のついたテーブル型 データ = ふがインスタンス.TableData;

とキャストしなくて良くなった。

ここで、重要だと思ったのが、

public abstract class ほにゃAbstract<T> where T:DataTable,new()

のwhere以降の部分で、Tに設定できる型の条件を指定できる。

T:DataTable

で、DataTableを基本型に持つクラスのみ指定可能なので、DataTableを継承した型である事という条件がクリアできる。

次に

new()

とつけることで、

private T _data = new T();

といったように抽象クラス側でインスタンスの生成ができるようになったので、いちいちサブクラス側でメンバを設定する必要が無くなった。

今更だし、凄い簡単な話なんだけど、便利だと思った。

そういえば、MSDNライブラリの型パラメータの制約ページの構文を説明している箇所で

http://msdn.microsoft.com/ja-jp/library/d5x73970.aspx

where T:struct

where T:class

のままで良いのに、

where T:構造体

where T:クラス

になっていた。

翻訳されすぎ。

Share

型付データセットを使うことで複雑なSQLはコードの外に追い出す

私のシステム設計の指針は複雑度の分散です。

だからコードの中に複雑なクエリは書きません。

問い合わせのクエリは、何らかの目的があって発行するものなので、JOIN等複数のテーブルが絡む複雑なクエリは、すべてRDBMS側にViewとして持つようにしています。

追記:2009年あたりから、ストアドも対象とするようにしました。

そのためのツールとして型付データセットを利用しています。

そうすることで、コードの中では常に一つのオブジェクト(テーブルであれVIEWであれ)に対して操作をするだけで済むので複雑なクエリが発行される事はありません。

それを実現するために、SQLを直接書かないでクエリを発行するためのフレームワークを作成してあります。

詳しくは書きませんが、型付データセット内で定義されているテーブル単位にラップしているクラスがあり、それに条件を積み上げたオブジェクトをアタッチする事で、様々なクエリを発行するようになっています。

ラップしているクラス自体の定義は前もって用意してあるテーブルにアクセスするための機能を持った抽象クラスを継承してテーブルを指定しているだけなので、数行で済むため作成やメンテナンスの労力はほぼありません。

SQLServerやOracleといった製品毎の差異もフレームワーク側で吸収(.NET Framework2.0にはその機能が実装されていて、そっちに移行しようか悩みました。)し、その中でクエリを自動生成するようにしているため、システムをコーディングするときは、仕様にあうように条件オブジェクトをブロックのように積み上げて、ラップしているクラスにアタッチするだけで良いです。

また、内部でパラメタライズドクエリ(+必要なエスケープ)を作成するためSQLInjectionといった問題も発生しません。

また、ラップするクラス名はテーブルやビューと同じ名前にしてある事と、ビューは目的に応じた名称にしている事から、何が目的でデータにアクセスしているのかが一目瞭然になっています。

この取り組みはもう4年以上続けていますが、

  • 複雑なクエリは外(RDBMS側)に目的に応じたVIEWとして持っている
  • クエリがコードの中に点在しない
  • コード内でデータにアクセスしている部分へのアクセスやコントロールがしやすい

などから昔のシステムでも保守にかける時間が少なくて済んでいます。

また、開発時にコードが複雑になりすぎないため、それ以前に比較すると不具合が少なかったり、不具合が発生してもそれにかける作業時間が少なく済んでいます。

コードの中に複雑なクエリを書いてしまって、修正が大変だとか嘆いている、そこのあなた。

コードにとっての保守フェーズはコードは書いた瞬間から始まっています。

とりあえず複雑なクエリはRDBMSに持ってもらう事でコードの見通しを良くしてみてはいかがでしょうか。

Share

チームマイナス6%

エコバック使おうとか、

比較的インパクトが少ない事は言えても、

電車で行けるところの国内線廃止とか、

電車で行けるところは飛行機を使うのを控えようとか、

各種国際会議等はビデオチャットを利用した分散会議とか(テロ対策にもなると思う。)、

分散オフィス促進とか、

海外旅行は控えて国内旅行にしようとか、

これから建築する建物は原則、外断熱にしろとか(一部の建物は最近、そういう原則が作られたけど)、

せめて無断熱な新築は犯罪にするとか、

アルミサッシは廃止で樹脂サッシにしようとか、

Q値(熱損失係数)という言葉を、もっと一般的にしようとか、

自分の家のQ値を知ろうとか、

エアコンの性能は固定の適用する畳数表示をやめて、容量の表示にしようとか、(Q値によっては、14畳用一つで全部屋まかなえる。うちはそう。)

という事は言えないんだよね。

だからって、どうという事は無いんだけど。

ところで排出権取引ってCO2削減に一切貢献していないのでは?

よく分からないで言っているけど。

カーボンオフセットTシャツっていうのには、笑った。

「このTシャツを買うと、一定量の排出権が買えるので差し引きCO2排出量が減ります。」

という趣旨なんだけど、ただの数字合わせだし、カーボンオフセットTシャツ自体の、製作や販売に係る部分については明らかにカーボンオフセットじゃ無いんだろうし。

まぁ、私個人の意見としては、CO2排出量削減に関しては特に言うことも思うこともないんだけれど、これまでの時代の流れをみても、ちょっとずつテクノロジが解決していく事だと思っています。

でも、この取り組みを特に批判しているわけでも否定しているわけでもなく、そう思ったというだけの話。

やらないよりは、やった方がましだし、継続する事で、いくつかの問題点が解消され取り組み自体が発展していくだろう。

というか、今までも発展してきたんだね。

ただ、ちょっと今の取り組み方(クールビズという名の我慢系とか)は続かないダイエットみたいだなと思った。

Share

まだ、SQLServer2005が最新版

現時点において、出荷されている製品としてはまだSQLServer2005が最新版である。

SQLServer2008はまだ未出荷だから最新版ではない。

当たり前の話だけど、勘違いしている人もいるようなので、とりあえずメモ。

Share

ATOK 2007 for Macを買った

IME2007よりはましだと思って、ことえりをだましだまし使っていたのだが、やっぱりATOKが恋しくなったので、ダウンロード購入をした。

WindowsではATOKユーザなので、まだ、インストールもしていないけど、使い勝手に期待。

Share
カテゴリー: Tool

どうも日本語コーディングが出来ない

日本語の変数名とかメソッド名とかクラス名といった識別子が使えないっぽい。

日本語でかけると良いんだけど。

できるという記事をどっかで見たような気もするんだけどなぁ。

まぁ、

識別子 (または 名前 (name)) は、以下の字句定義で記述されます:

identifier ::= (letter|”_”) (letter | digit | “_”)*

letter ::= lowercase | uppercase

lowercase ::= “a”…”z”

uppercase ::= “A”…”Z”

digit ::= “0”…”9″

http://www.pinkdragon.net/doc_lib/contents/ja/python_man/ref/identifiers.html

を見る限りは出来ないで正解だとは思うんだけど。

Share

それにしても口唇ヘルペスに初めてなりました。

唇の下がいたいやら痒いやら、リンパが腫れてちょっと痛いし、同居人に感染させないように気を使う必要があるやらで疲れ気味。

疲れ気味だから感染するんだけども。

まぁ、薬を貰ったので早く治ったら良いなぁ。

最近の生活リズム崩しまくりで変な時間にしか眠れないのもあったので、そこを改善する必要あり。

Share