2012年10月28日

Visual Studio 2012 便利機能

今回も知人より寄稿してもらいました。この場を借りて感謝します。
※ 前回の記事(Visual Studio 2012 Web機能)もよろしくどうぞ。

Visual Studio 2012
-- セミナーフィードバック その2 --



この夏〜秋のMicrosoftセミナーを梯子しました。
今回はその中でも特に、Visual Studio 2012の新機能で便利そうな印象を受けた機能を、備忘録としてまとめたいと思います。
※ 一部機能はVisual Studio 2010でも拡張機能をインストールすると利用できます。前回投稿した記事とあわせて、Visual Studio の拡張機能については、別の記事としてまとめる予定です。


ソリューションエクスプローラー



Visual Studioでファイルや関数などを探す時、「ctrl+shift+f」で検索し、検索結果に表示された一覧から、自分の探しているものを見つけていました。
「えいや!」の一発で見つかることもあれば、一通り確認しても目的のものが見つからなかった時もありました。
そんな時は、たくさん開いてしまったファイルタブのおかげで、当初開いていたファイルタブが深い所に埋もれてしまうこともしばしばありました。

そんな私に朗報が!
それがソリューションエクスプローラーの検索機能です。
検索した項目にヒットしたものだけでソリューションエクスプローラーが構成されます。
沢山のノードを開いて閉じてと探す手間がなくなりました。
しかもこの検索機能の便利なところは、ファイル(クラス)だけじゃなく、メンバー(関数や変数)まで検索できてしまうことです。
ソリューション検索

※ 少し難をいえば、上記の機能はWebサイトプロジェクトでは利用できません。(WebアプリケーションならばOK)コードメトリクスの機能もWebサイトでは利用できないなど、Webサイトの冷遇っぷりに、涙で袖を濡らしました。

そしてソリューションエクスプローラーの検索に抱き合わせで利用できる、Viewタブ。
検索にヒットしたファイルが、自分の探し求めているファイルか確認するために、ファイルの中身を参照する際、Viewタブで開けば新しいタブがどんどん増えてゆくということもありません。
Viewタブが一番右側に一つ設けられ、そのタブの中身が切り替わることで、ファイルの中身を確認できます。

無駄なタブを開かなくてもOKというのは、結構使い勝手が良いです。
それに関連して、地味に便利な機能として、画像ファイルのホバー表示があります。
画像ファイルの中身を確認するのに、わざわざファイルを開かなくても、画像ファイルにカーソルを当てれば、画像イメージが表示されるのです。
画像のホバー表示

検索機能の強化



ソリューションエクスプローラーもそうですが、Visual Studio 2012は全体的に検索機能が強化されています。
沢山存在しているツールボックスのコントロールも検索で見つけることができます。
ツールボックスの検索
※ 上記の画像のように、ドラッグドロップで追加したJavaScriptの「hoge」という関数(「全般」タグに属しています)も含めて検索することができます。

また、Visual Studio全体に対して、検索することも可能です。
設定を変更したいなど、日常的に利用しない機能は階層が深い所にあり、基本覚えていません。
探すのに時間がかかりますし、見つからない時にはWebで調べるなどVisual Studioを離れないといけません。
そんな作業ロスが少なくなりそうです。


Page Inspector



※ 前回に引き続き、Web系のお話になってしまうのですが。。
ASP.NETをやり始めて間もなかった時。初めて自分の作成したWebサイトのページのソースの表示をしたとき、そこで確認できるHTMLが、開発で作っていたaspxとずいぶん違っていたことにびっくりしました。

Page Inspectorを利用すれば、ブラウザにレンダリングされたUIとaspx上のサーバーコントロールを紐付けて確認することが可能です。
もちろん、UIとDOM要素の紐付け、各要素ごとのスタイルの把握も行えますが、これらの機能は、各ブラウザに搭載されている開発ツールでも利用可能な機能で、それほど目新しさはありません。

以下には、個人的なPage Inspectorに対して抱いた所感をまとめたいと思います。

所感@
サーバーコントロールを含めて紐付けがおこなえることの意義が、あまり感じられませんでした。
ASP.NETの経験が浅かった頃、aspxがHTMLに展開された時には、ソースの表示で戸惑いもありましたが、現在は「大体こんな感じで紐づいているのかな」というのはわかります。
これはあくまで個人的な意見になります。
正直、ユーザーコントロールの中身まで検証してくれた時には、「おぉ!すばらしい!」と感動しました。
Page Inspector ユーザーコントロール
※ こちらの図では、テキストボックスとボタンのグループをユーザーコントロールとして作成しています。テキストボックスの要素を検証した際には、ユーザーコントロール内のテキストボックスがハイライトされています。

ASP.NETのWebフォームのサーバーコントロールがどのようなDOMになるのか、勉強する過程にこれらはとても有用な機能だと思います。
※ サーバーコントロールは、複数のDOMのまとまりをプログラマーが意識することなく、1つの抽象的なコントロールとして利用できるところがポイントだと、当初言われていたことを不意に思い出しました。
現在は(DOMを厳密に把握し、それを踏まえてスタイルしていくため)そんなことを言ってはいられないのでしょうね。

所感A
JavaScriptのデバッグが行えなかったことは少し残念でした。
JavaScriptはUIの形成に深く関わる部分になるため、Page Inspector(ページ検証)機能として、JavaScriptのデバッグは是非ほしいものだと思いました。

Visual Studio上でJavaScriptのデバッグは可能ですが、それはPage Inspectorとはまったく独立した機能として提供されています。
そしてデバッグの際にはブラウザとVisual Studioの行き来が発生してしまい、各ブラウザに付属の開発者ツールに比べて、画面の切り替えなどが少し煩雑である印象があります。
しかも、Visual Studio上でJavaScriptをデバッグ中は、IEの開発者ツールでJavaScriptのデバッグができなくなるため(Visual StudioのほうでJavaScriptデバッグプロセスにアタッチしてしまっているため)、IEの開発者ツールで、DOMの検証・スタイルの確認・JavaScriptのデバッグを一元的に行える状況を阻害します。
DOMの検証・スタイルの確認と紐付けて利用できないVisual StudioのJavaScriptのデバッグ機能をあえて利用するメリットは、特に思いつきません。

現在はブラウザの検証ツールには、もっぱらChromeの開発者ツールのお世話になっています。
Chromeはサーバーコントロールと紐付けて検証などできませんが、多くの便利機能を備えているため、作業効率化に寄与してくれています。
ただ、Visual Studio内で完結できるのならば、それに越したことはないと思っています。
このPage InspectorはVisual Studio 2012で初めて搭載された機能ですので、今後どのような成長を遂げるか、期待しています。
最終的には、IEの開発者ツールで行えるようなことが、Visual Studioに含められたら最高!って手前勝手ながら願っています。



posted by ぺるたご at 22:06| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2012年10月14日

CSVインポートをデザインパターンで実装してみる

今回はデザインパターンを使ってCSVのインポート機能を実装してみます。デザインパターンという名前は有名ですが、どんなときに使ったらいいのかが悩みどころ。

サンプルコードはC#4.0+.NET Framework 4で実装していますが、古いバージョンでもたぶん動きます。VB使いの人は・・・、適当に読み替えてください。



仕様

画面のボタンを押したらユーザーのデータが書かれたCSVファイルを読み込み、それをUserデータクラスのコレクション(今回はList<User>)に格納する。CSVの中身は以下のような感じ。

01,ももこ,8
02,ひろし,40
03,すみれ,40
04,さきこ,11
05,ともぞう,76



とりあえず実装

とりあえず仕様を満たすように実装してみましょう。特に何の工夫もなく、以下のような感じで。

とりあえず実装
//ボタンのイベントハンドラ
private void button1_Click(object sender, EventArgs e)
{
string fileName = "C:\\user.csv";
List<User> userList = new List<User>();
using (TextFieldParser parser = new TextFieldParser(fileName))
{
parser.Delimiters = new string[] { "," };
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields();
User user = new User();
user.UserCode = fields[0];
user.UserName = fields[1];
user.Age = Convert.ToInt32(fields[2]);
userList.Add(user);
}
}
}

//データクラス
public class User
{
public string UserCode { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
}



CSVの読み込みにはTextFieldParserクラスを使っています。こいつはMicrosoft.VisualBasic.FileIO名前空間のクラスなので、C#から使うときはusingでインポートしましょう。Userクラスはユーザーのデータを格納する単なる入れ物です。

とにかく仕様どおりに動くプログラムができました。それではケチをつけていきます。
 ・CSVインポート機能って他でも使いそうなので、Formクラスに書きたくない。
 ・「CSVを読み込む処理」と「データクラスに詰め直す処理」が同じ関数内に書かれてて何か嫌。
 ・他のCSV(例えば住所とか)もインポートするようになったら、冗長な記述が増えそう。




Strategyパターンで実装してみる

Strategyパターンとは、ロジックを別クラスに切り出して簡単に差し替えられるようにしようよ、ってパターンです。

Strategyパターンで実装
//ボタンのイベントハンドラ
private void button1_Click(object sender, EventArgs e)
{
string fileName = "C:\\user.csv";
//ロジックの差し替えポイント。
CsvImporter<User> csv = new CsvImporter<User>(new UserCsvAnalysis());
List<User> userList = csv.Import(fileName);
}

//データクラス(ユーザー)
public class User
{
public string UserCode { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
}

//データクラスへの詰め替え機能を司るインターフェイス
public interface ICsvAnalysisStrategy<T>
{
T Analyze(string[] csvFields);
}

//ユーザーCSVの1行をデータクラスに詰め替えるクラス
public class UserCsvAnalysis : ICsvAnalysisStrategy<User>
{
public User Analyze(string[] csvFields)
{
User user = new User();
user.UserCode = csvFields[0];
user.UserName = csvFields[1];
user.Age = Convert.ToInt32(csvFields[2]);
return user;
}
}

//CSVインポートの窓口的なクラス
public class CsvImporter<T>
{
private ICsvAnalysisStrategy<T> analyzer;

public CsvImporter(ICsvAnalysisStrategy<T> analyzer)
{
this.analyzer = analyzer;
}

public List<T> Import(string fileName)
{
List<T> list = new List<T>();
using (TextFieldParser parser = new TextFieldParser(fileName))
{
parser.Delimiters = new string[] { "," };
while (!parser.EndOfData)
{
list.Add(analyzer.Analyze(parser.ReadFields()));
}
}
return list;
}
}



Strategyパターンの肝としては、ロジックを司るクラス(ここではデータ詰め替え用のUserCsvAnalysisクラス)にインターフェイスを付けておきます。インターフェイスを付けた各クラスは「同じような物」として扱えます。「同じような物」だから簡単に差し替えられる、という理屈です。

コード中に出てくる「T」というのはデータクラスの型、ここではUserクラスのことです。ユーザーだけでなく、別のCSV(例えば住所とか)をインポートすることを見越して、ジェネリックで一般化しています。

では、さきほどケチをつけたポイントについて確認してみます。

・CSVインポート機能って他でも使いそうなので、Formクラスに書きたくない。
 →インポート機能をFormクラス以外に分離したのでどこからでも使えます。

・「CSVを読み込む処理」と「データクラスに詰め直す処理」が同じ関数内に書かれてて何か嫌。
 →「CSVを読み込む処理」はCsvImporter<T>クラス、「データクラスに詰め直す処理」はUserCsvAnalysisクラスに分離されてます。

・他のCSV(例えば住所とか)もインポートするようになったら、冗長な記述が増えそう。
 →この点については、実際に住所CSVもインポートできるように改造してみましょう。




住所CSVもインポートできるようにしてみる

前回からの変更点を赤文字にしています。

住所CSVもインポートできるようにしてみる
//ボタンのイベントハンドラ
private void button1_Click(object sender, EventArgs e)
{
string fileName = "C:\\user.csv";
//ロジックの差し替えポイント。ユーザー用と住所用を差し替える。
CsvImporter<Address> csv = new CsvImporter<Address>(new AddressCsvAnalysis());
List<Address> addressList = csv.Import(fileName);
}

//データクラス(ユーザー)
public class User
{
public string UserCode { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
}

//データクラス(住所)
public class Address
{
public string ZipCode { get; set; }
public string Prefecture { get; set; }
public string City { get; set; }
public string StreetNumber { get; set; }
}


//データクラスへの詰め替え機能を司るインターフェイス
public interface ICsvAnalysisStrategy<T>
{
T Analyze(string[] csvFields);
}

//ユーザーCSVの1行をデータクラスに詰め替えるクラス
public class UserCsvAnalysis : ICsvAnalysisStrategy<User>
{
public User Analyze(string[] csvFields)
{
User user = new User();
user.UserCode = csvFields[0];
user.UserName = csvFields[1];
user.Age = Convert.ToInt32(csvFields[2]);
return user;
}
}

//住所CSVの1行をデータクラスに詰め替えるクラス
public class AddressCsvAnalysis : ICsvAnalysisStrategy<Address>
{
public Address Analyze(string[] csvFields)
{
Address address = new Address();
address.ZipCode = csvFields[0];
address.Prefecture = csvFields[1];
address.City = csvFields[2];
address.StreetNumber = csvFields[3];
return address;
}
}


//CSVインポートの窓口的なクラス
public class CsvImporter<T>
{
private ICsvAnalysisStrategy<T> analyzer;

public CsvImporter(ICsvAnalysisStrategy<T> analyzer)
{
this.analyzer = analyzer;
}

public List<T> Import(string fileName)
{
List<T> list = new List<T>();
using (TextFieldParser parser = new TextFieldParser(fileName))
{
parser.Delimiters = new string[] { "," };
while (!parser.EndOfData)
{
list.Add(analyzer.Analyze(parser.ReadFields()));
}
}
return list;
}
}




どうでしょう?「CSVを読み込む処理」を司るCsvImporter<T>クラスは全く変更されていません。変更されているのはまさに「住所」に関する部分だけです。

ではまたケチを付けてみましょう。
CsvImporter<Address> csv = new CsvImporter<Address>(new AddressCsvAnalysis());
「ロジックの差し替えポイント」において「Address」と「AddressCsvAnalysis」が冗長です。住所用の詰め替えロジックを使ったら、戻り値は住所に決まってますから。ということで、「詰め替えロジックのインスタンスを作る処理」を別クラスに切り出します。いわゆるFactoryですね。「サルでもわかる 逆引きデザインパターン」を参考にしています。



Factoryクラスを作ってみる

前回からの変更点を赤文字にしています。

Factoryクラスを作ってみる
//ボタンのイベントハンドラ
private void button1_Click(object sender, EventArgs e)
{
string fileName = "C:\\user.csv";
//ロジックの差し替えポイント。
CsvImporter<Address> csv = new CsvImporter<Address>(/*引数を撤去*/);
List<Address> addressList = csv.Import(fileName);
}

//データクラス(ユーザー)
public class User
{
public string UserCode { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
}

//データクラス(住所)
public class Address
{
public string ZipCode { get; set; }
public string Prefecture { get; set; }
public string City { get; set; }
public string StreetNumber { get; set; }
}

//データクラスへの詰め替え機能を司るインターフェイス
public interface ICsvAnalysisStrategy<T>
{
T Analyze(string[] csvFields);
}

//ユーザーCSVの1行をデータクラスに詰め替えるクラス
public class UserCsvAnalysis : ICsvAnalysisStrategy<User>
{
public User Analyze(string[] csvFields)
{
User user = new User();
user.UserCode = csvFields[0];
user.UserName = csvFields[1];
user.Age = Convert.ToInt32(csvFields[2]);
return user;
}
}

//住所CSVの1行をデータクラスに詰め替えるクラス
public class AddressCsvAnalysis : ICsvAnalysisStrategy<Address>
{
public Address Analyze(string[] csvFields)
{
Address address = new Address();
address.ZipCode = csvFields[0];
address.Prefecture = csvFields[1];
address.City = csvFields[2];
address.StreetNumber = csvFields[3];
return address;
}
}

//CSVインポートの窓口的なクラス
public class CsvImporter<T>
{
private ICsvAnalysisStrategy<T> analyzer;

public CsvImporter(/*引数を撤去*/)
{
this.analyzer = CsvAnalysisFactory<T>.Create();
}

public List<T> Import(string fileName)
{
List<T> list = new List<T>();
using (TextFieldParser parser = new TextFieldParser(fileName))
{
parser.Delimiters = new string[] { "," };
while (!parser.EndOfData)
{
list.Add(analyzer.Analyze(parser.ReadFields()));
}
}
return list;
}
}

//詰め替えロジックのインスタンスを作るクラス
public static class CsvAnalysisFactory<T>
{
public static ICsvAnalysisStrategy<T> Create()
{
if (typeof(T) == typeof(User))
{
return new UserCsvAnalysis() as ICsvAnalysisStrategy<T>;
}
else if (typeof(T) == typeof(Address))
{
return new AddressCsvAnalysis() as ICsvAnalysisStrategy<T>;
}
return null;
}
}




新設したCsvAnalysisFactory<T>クラスでは、ジェネリック引数Tによってどの詰め替えロジックを使うかを判断しています。以前は画面側で判断していたので、これで、画面側プログラマがどうやってインスタンスを作るか悩む必要がなくなります。今回は引数もプロパティも与えないので悩むこともありませんが・・・。この状態のクラス図は以下のようになります。

CSVインポートのクラス図


ここまででいったん完成としますが、試しに仕様を追加してみましょう。
・CSVの種類によってはヘッダー行が存在しています。
・ヘッダーのありなしはCSVの種類によって固定です。
・ヘッダー行はインポートしたくありません。
・ヘッダー行は1行目だけです。




ヘッダー行のありなしを実装してみる

前回からの変更点を赤文字にしています。

ヘッダー行のありなしを実装
//ボタンのイベントハンドラ
private void button1_Click(object sender, EventArgs e)
{
string fileName = "C:\\user.csv";
//ロジックの差し替えポイント。
CsvImporter<Address> csv = new CsvImporter<Address>();
List<Address> addressList = csv.Import(fileName);
}

//データクラス(ユーザー)
public class User
{
public string UserCode { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
}

//データクラス(住所)
public class Address
{
public string ZipCode { get; set; }
public string Prefecture { get; set; }
public string City { get; set; }
public string StreetNumber { get; set; }
}

//データクラスへの詰め替え機能を司るインターフェイス
public interface ICsvAnalysisStrategy<T>
{
bool HasHeader { get; }
T Analyze(string[] csvFields);
}

//ユーザーCSVの1行をデータクラスに詰め替えるクラス
public class UserCsvAnalysis : ICsvAnalysisStrategy<User>
{
//ヘッダー行あり
public bool HasHeader { get { return true; } }

public User Analyze(string[] csvFields)
{
User user = new User();
user.UserCode = csvFields[0];
user.UserName = csvFields[1];
user.Age = Convert.ToInt32(csvFields[2]);
return user;
}
}

//住所CSVの1行をデータクラスに詰め替えるクラス
public class AddressCsvAnalysis : ICsvAnalysisStrategy<Address>
{
//ヘッダー行なし
public bool HasHeader { get { return false; } }

public Address Analyze(string[] csvFields)
{
Address address = new Address();
address.ZipCode = csvFields[0];
address.Prefecture = csvFields[1];
address.City = csvFields[2];
address.StreetNumber = csvFields[3];
return address;
}
}

//CSVインポートの窓口的なクラス
public class CsvImporter<T>
{
private ICsvAnalysisStrategy<T> analyzer;

public CsvImporter()
{
this.analyzer = CsvAnalysisFactory<T>.Create();
}

public List<T> Import(string fileName)
{
List<T> list = new List<T>();
using (TextFieldParser parser = new TextFieldParser(fileName))
{
parser.Delimiters = new string[] { "," };
if (analyzer.HasHeader)
{

//ヘッダーありの場合は1行読み飛ばす。
parser.ReadLine();
}

while (!parser.EndOfData)
{
list.Add(analyzer.Analyze(parser.ReadFields()));
}
}
return list;
}
}

//詰め替えロジックのインスタンスを作るクラス
public static class CsvAnalysisFactory<T>
{
public static ICsvAnalysisStrategy<T> Create()
{
if (typeof(T) == typeof(User))
{
return new UserCsvAnalysis() as ICsvAnalysisStrategy<T>;
}
else if (typeof(T) == typeof(Address))
{
return new AddressCsvAnalysis() as ICsvAnalysisStrategy<T>;
}
return null;
}
}




ヘッダーのありなしはCSVの種類に固有の話なので、詰め替え機能を司るインターフェイス(ICsvAnalysisStrategy<T>)にHasHeaderプロパティを追加しました。あとは、「ヘッダー行は読み込まない」という仕様なので、インポートの窓口クラス(CsvImporter<T>)で読み飛ばすように処理を追加しています。



まとめ


Strategyパターンはわりと使う機会がありそうです。使いどころとしては、if文で似たようなロジックに分岐しているところでしょうか。





posted by ぺるたご at 22:46| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2012年10月13日

Visual Studio 2012 Web機能

今回も知人より寄稿してもらいました。この場を借りて感謝します。
※ 前回の記事(Microsoft Conference 2012に参加してきました。)もよろしくどうぞ。

Visual Studio 2012
-- セミナーフィードバック その1 --



この夏〜秋のMicrosoftセミナーを梯子しました。
その中でも特に、Visual Studio 2012のWeb系の便利そうな印象を受けた機能を、備忘録としてまとめたいと思います。(個人的にWeb系のお仕事が多いので)
※ 一部機能はVisual Studio 2010でも拡張機能をインストールすると利用できます。ただ、それを記載し始めると長くなってしまうため、ここでは拡張機能を入れていない状態のVisual Studio 2010とVisual Studio 2012を比較して便利だと思った箇所をまとめます。
(Visual Studio に拡張機能を入れた場合、2010と2012でどのようなことが出来るようになるのかは、次回まとめて公開できればと思っています)


● [マイクロソフト ソリューション セミナー] 新製品 Visual Studio 2012 概要〜新世代の統合開発環境で実現するこれからのアプリケーション開発とは
● The Microsoft Conference 2012
● Developer Camp 2012


Web系開発・便利機能まとめ


Webを構成する技術のHTML/JavaScript/CSS、これらを開発する際の便利機能を、所感を交えながら記載します。

(1) HTML


タグをサクサクと作成(HTML5にもバッチリ対応)


まずはこちらのHTMLを見てください。

HTML5のvideoタグ

<video controls="controls">
<source src="hoge.mp4" type="video/mp4" />
<source src="hoge.webm" type="video/webm" />
<source src="hoge.ogv" type="video/ogg" />
</video>


HTML5のvideoタグになるのですが、こちらをVisual Studio 2012で記載する際のステップは、
@.「<vi」とタイプ → インテリセンスのvideoを選択!
A.タブタブ♪ → videoタグの雛形が出力されます。
B.デフォルトで、1行目のsourceタグのsrc属性にフォーカスが設定されています。その値を変更すると、2行目・3行目のsrc属性も連動して変更されます。(デフォルトでは「test」と表示されていたものを「hoge」に変更しました。)

videoタグの作成が、キーボードを5回タイプ(+ファイル名の文字数)で完了です!


タグのサクサクとリファクタ


まずはこちらのHTMLを見てください。

タグのリファクタ

<div>
<!--たくさんの入れ子になっているタグ…-->
</div>


こちらのdiv要素をHTML5っぽいタグに変更したいと思った場合、そのdivの中には、「たくさんの入れ子になっているタグ」が。。終わりの「div」はどれ?なんだか違うタグを変更してしまった!など、タグを変更する場合、ちょこっと面倒だったりします。
Visual Studio 2012のHTMLエディターでは、<div>を<section>に変更すると、連動して紐付く終了タグが</div>から</section>になってくれるんです。
Demoで見たときに、「おぉ、これは便利!」と思いました。
※ 終了タグを修正した場合は開始タグが連動して修正されます。


よく使うタグの塊をユーザーコントロールにサクサクと変換


気がついたら、HTMLで似たようなタグの構成のものが、複数ペ ージに書かれていることがあります。
セッセとコピペするよりは、ユーザーコントロールにしてしまうほうが、再利用性が高まります。
Visual Studio 2012では、以下のステップで簡単にユーザーコントロールとして抽出することが出来ます。
@.タグの塊を選択
A.右クリック → ユーザーコントロールに展開
すると、「.ascx」拡張子のユーザーコントロールがWebプロジェクト内に追加されます。
と、同時にユーザーコントロールに展開した部分のタグが、ユーザーコントロールに置き換わってくれています。
気が利いてて良いなぁって思いました。


(2) JavaScript


かゆい所に手が届く、コードの可読性を上げる機能モロモロ


JavaScriptエディターも随分使い勝手が上がった印象を受けました。
関数の折り畳みが出来たり、カッコの開始と終了の照合が出来たり、関数や変数の定義にジャンプ出来たり。。
「待ってました!」な機能が盛りだくさんでした。


何でもアリのJavaScriptを厳格に制御!


JavaScriptのファイル内に、"use strict";という1行を書き込むと、そのJavaScriptファイルは厳格モードになります。
例えば、「function hoge(a, a)」みたいに、「関数の引数が同じ変数名?!」などというコードには、Visual Studioおなじみの波線が表示されて、不正な書き方であることを教えてくれます。
※ ただ、このエラーはビルドが通らない類のエラーではありません。


JavaScriptの単体テストも自動化できちゃう!


Visual Studio 2010でASP.NETを開発した時、サーバーサイドロジックの単体テストの自動化をやり始めて、「これは便利!」とゴリゴリテストコードを書きました。
いろんなパターンのデータでテストが楽々行えて、反復可能。関数リファクタ後の動作検証もハードルが下がり、リファクタ三昧!ヒャッハー!
しかし、そこでハタと気づきました。
JavaScriptファイルの中身も結構盛りだくさん。ロジックたっぷりだけど、JavaScriptファイルの単体テストは自動化できないということに。。!
Visual Studio 2012ではその悔しさも消し飛びます。


(3) CSS


至れりつくせりのカラーピッカー


色を指定する際に、「#」と入力すると、カラーピッカーが表示されます。
カラーピッカーは、グラフィカルな色の選択、透明度の指定、さらに、Visual Studioの外から色を抽出することもできます。
これで「色は何にしようかな」と思ったときに、Visual Studioから離れて別のツールを使う手間がぐっと減ると思いました。
カラーピッカー

ゴチャリンコになりがちなCSSをregionですっきりグルーピング


「Regionディレクティブ」、どれだけこれのお世話になったことか。。!
Visual Studio 2012ではその「Region」をCSSでも利用できるようになります。
整理整頓で保守・可読性がアップしそうな予感です。

cssのregionディレクティブ

/*#region ××エリア*/
/*××エリアに係るモロモロのcss*/
/*#endregion*/





posted by ぺるたご at 00:16| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。