一番の収穫はやはり LINQ to SQL。
つか、LINQ to SQL の場合、where 句のラムダ式が SQL の where 句に変換されるというのは、正直半信半疑だった。
で、帰宅して早速試してみた。
static void Main(string[] args)
{
DataContext context = new DataContext(Settings.Default.Database1ConnectionString);
var query =
from target in context.GetTable<Table1>()
where (target.Column1 == "a")
select target;
string queryText = query.ToString();
Console.WriteLine(queryText);
}
[Table(Name = "Table1")]
class Table1
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
public int PrimaryKey;
[Column]
public string Column1;
}
実行結果
SELECT [t0].[PrimaryKey], [t0].[Column1]
FROM [Table1] AS [t0]
WHERE [t0].[Column1] = @p0
Σ(゚д゚lll)ガーン
ホントに where 句が where 句に・・・!
そういや、LINQ to SQL のラムダ式はデリゲートではなく System.Linq.Expressions.Expression オブジェクトに変換されると言っていたな。
逆コンパイルしてみると、確かに・・・つーか結構複雑なことやってるな。target.Column1 == "a" というラムダ式から、target とか Column1 とか == 演算子なんかのメタデータを採取して、それを元に Expression オブジェクトを構築するようなコードへと変換されている。
なるほどなるほど。
でもまぁこんなクエリー式はさすがに無理だろ。
var query =
from target in context.GetTable<Table1>()
where (target.Column1[1].ToString() == "a")
where (target.Column1.IndexOf("b") <= 3)
select target;
実行結果
SELECT [t0].[PrimaryKey], [t0].[Column1]
FROM [Table1] AS [t0]
WHERE ((
(CASE
WHEN (DATALENGTH(@p0) / 2) = 0 THEN CONVERT(BigInt,0)
ELSE CONVERT(BigInt,(CONVERT(Int,CHARINDEX(@p0, [t0].[Column1]))) - 1)
END)) <= @p1) AND ((CONVERT(NVarChar(MAX),CONVERT(NChar(1),SUBSTRING([t0].[Column1], @p2 + 1, 1)))) = @p3)
( ゚Д゚ ) ・・・。
"(VS.80)" 有り
IConfigurationSectionHandler インターフェイス (System.Configuration)
"(VS.80)" 無し
IConfigurationSectionHandler インターフェイス (System.Configuration)
で、今度は ConfigurationSection クラスだと、"(VS.80)" が付いている方には「メモ : このクラスは、.NET Framework version 2.0 で新しく追加されたものです。」と書かれているのに "(VS.80)" が付いていない方には書かれていません。
"(VS.80)" 有り
ConfigurationSection クラス (System.Configuration)
"(VS.80)" 無し
ConfigurationSection クラス (System.Configuration)
しかも、よくよく眺めてみると、他にもちらほら違いがあります。
で、更によくよく見ると、"(VS.80)" が付いているページと付いていないページとでは、ページ階層も異なるようで、"(VS.80)" が付いているページは「以前のバージョン」というページの下の方にぶらさがっているようです。
まぁ、だからどうしたと言う訳でもなく、ただそれだけです。
ページによっては、URL から "(VS.80)" を除いたとしても勝手に補完される場合もあるようです。
static void Main()
{
Image page1 = new Bitmap("C:\\work\\page1.bmp");
Image page2 = new Bitmap("C:\\work\\page2.bmp");
Image page3 = new Bitmap("C:\\work\\page3.bmp");
// まず、1ページ目となる画像を指定しておく。
Image tiff = new Bitmap(page1);
// TIFF 形式のエンコーダ。
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
Predicate<ImageCodecInfo> tiffEncoderPredicate =
delegate(ImageCodecInfo input)
{
return (input.FormatID == ImageFormat.Tiff.Guid);
};
ImageCodecInfo tiffEncoder = Array.Find(imageEncoders, tiffEncoderPredicate);
// エンコーダのパラメータ。
EncoderParameters tiffEncoderParameters = new EncoderParameters(1);
tiffEncoderParameters.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
// 作業領域となるメモリストリーム。
MemoryStream tiffStream = new MemoryStream();
// Save メソッドによって、1ページ目が保存され、更に Image オブジェクトとメモリストリームが関連付けられる。
tiff.Save(tiffStream, tiffEncoder, tiffEncoderParameters);
// 2ページ目, 3ページ目の保存に使用するエンコーダのパラメータ。
EncoderParameters pageEncoderParameters = new EncoderParameters(2);
pageEncoderParameters.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
pageEncoderParameters.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone);
// 先ほどの Save メソッドで関連付けられたメモリストリームに対して保存される。
tiff.SaveAdd(page2, pageEncoderParameters);
tiff.SaveAdd(page3, pageEncoderParameters);
// メモリストリームの内容をファイルに保存する。
File.WriteAllBytes("C:\\work\\test.tif", tiffStream.ToArray());
}
EncoderParameter のインスタンスを生成する際、EncoderValue 列挙値を long にキャストして渡しています。これは int ではなく long にしなければいけません。でないと失敗します。
サンプルなんで Dispose メソッドは呼び出してません。Image, MemoryStream 以外にも、EncoderParameters や EncoderParameter も IDisposable を実装してます。
このブログの WCF の記事、全部日本語ページへのリンクに張り替えないと。。。
ダウンロードの詳細 : VS2005 SP1 Update for Vista
HttpCapabilitiesBase.JavaScript プロパティ
すごいなこれ^^;
まぁ、以下の部分が理由でしょうね。
ブラウザが JavaScript をサポートしていても、セキュリティの設定でスクリプトが無効になっている場合、JavaScript プロパティは true を返しますが、ブラウザでスクリプトは実行されません。
でも、最近入ってきた仕事でWCFを使ったWebサービスの開発を行うことになりそうです。
今はWCFの調査段階で、サンプルプログラムの作成中。そして、「そうだ、クライアント側はWPFで作ろう」という素晴らしい名案が浮かびましたので、WPFの調査も ( 勝手に ) 行っています。
WCFとWPFのお勉強を業務の一環としてできるという、なんともラッキーな状況です。 ( まぁ、さすがにWPFの方は深くつっこんで勉強するわけにはいきませんが^^; )
とりあえず、WCFの勉強に使っているサイトと、WPFの勉強に使おうと思っているサイトを貼り付けておきます。
Windows Communication Foundation概説 − @IT
WPF アプリケーションを作る クッキングガイド
あと、↓の辺も抑えておきたいですね。 ( オレが。 )
Windows Communication Foundation アーキテクチャの概要
Windows Communication Foundation による高信頼メッセージングについて
Windows Presentation Foundation - ホーム
.NET Framework 3.0 や、Visual Studio 2005でWPF/WCF開発を行うためのアドインの入手に関しては、こちらの記事を参照してください。
.NET Framework 3.0 正式版 リリース
MSDNには以下のように記載されている。
[ MemberAccessException ]
呼び出し元には、(たとえば、メソッドがプライベート メソッドの場合に) デリゲートが表すメソッドへのアクセス権がありません。 または args にリストされているパラメータの数、順序、または型が無効です。
[ TargetException ]
デリゲートが表すメソッドがインスタンス メソッドであり、対象オブジェクトが null 参照 (Visual Basic では Nothing) です。 または デリゲートが表すメソッドが、そのメソッドをサポートしないオブジェクトまたはクラスに対して呼び出されています。
[ TargetInvocationException ]
カプセル化されたメソッドの 1 つが例外をスローします。
しかし、TargetInvocationException以外の例外&説明は、実際と全く異なる。
第一に、デリゲートが表すメソッドがプライベートメソッドだろうが、そのメソッドがプライベートメソッドを呼び出していようが、例外なんて発生しない。また、デリゲートが表すメソッドの要求するアクセス許可が呼び出し元になくて、System.Security.SecurityExceptionがスローされる場合も、MemberAccessExceptionなどスローされず、 ( SecurityExceptionをラップした ) TargetInvocationExceptionがスローされる。
第二に、argsにリストされているパラメータの数、順序、型が無効な場合でも、MemberAccessExceptionはスローされない。パラメータ の数が不正な場合はTargetParameterCountExceptionがスローされ、順序や型が向こうな場合は ArgumentExceptionがスローされる。
第三に、 「 デリゲートが表すメソッドがインスタンス メソッドであり、対象オブジェクトがnull参照 」 なんて状況はありない。 「 対象オブジェクトがnull参照 」 というのは、対象オブジェクトがGCに回収されている状況を指しているのだろうが、デリゲートが存在する限り対象オブジェクトがGCに回収されることはない。デリゲートのTargetプロパティにしっかりと対象オブジェクトの"強い"参照が保持されているから。
第四に、 「 デリゲートが表すメソッドが、そのメソッドをサポートしないオブジェクトまたはクラスに対して呼び出されています。 」 なんて状況もありえない。
まず、以下のように、デリゲートオブジェクトを普通に作成した場合、当然、メソッドとオブジェクトは正しく結びつく。
public delegate void SimpleMethod();
class Class1
{
public Class1()
{
}
public void Method1()
{
Console.WriteLine("Method1 was called.");
}
}
class Program
{
static void Main(string[] args)
{
Class1 obj = new Class1();
Delegate objMethod1 = (SimpleMethod)obj.Method1;
objMethod1.DynamicInvoke();
Console.ReadLine();
}
}
また、リフレクションを使って作成したとしても、無関係のオブジェクトと関連付けて作成することは不可能である。
public delegate void SimpleMethod();
class Class1
{
public Class1()
{
}
private void Method1()
{
Console.WriteLine("Method1 was called.");
}
}
class Program
{
static void Main(string args)
{
Assembly thisAssembly = Assembly.GetExecutingAssembly();
Type class1 = thisAssembly.GetType("Class1");
MemberInfo[] class1Member = class1.GetMember("Method1", MemberTypes.Method, BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo class1Method1Info = class1Member[0] as MethodInfo;
// 以下のコードでは、実行時に例外がスローされる。
// Delegate class1Method = Delegate.CreateDelegate(typeof(SimpleMethod), new Object(), class1Method1Info);
Delegate class1Method = Delegate.CreateDelegate(typeof(SimpleMethod), new Class1(), class1Method1Info);
class1Method.DynamicInvoke();
Console.ReadLine();
}
}
( ついでに、対象メソッドの可視性はプライベートにしてある。 )
で、結局のところ、Delegate.DynamicInvokeメソッドの例外は、正しくは以下のようになる。
[ System.ArgumentException ]
args にリストされているパラメータの順序、または型が無効である場合にスローされる。
[ System.Reflection.TargetParameterCountException ]
args にリストされているパラメータの数が、必要なパラメータ数と異なる場合にスローされる。
[ System.Reflection.TargetInvocationException ]
カプセル化されたメソッドの 1 つが例外をスローする場合にスローされる。
テキストファイルやXMLファイルなど、全てのファイルはアセンブリに埋め込んで利用することができる。
ファイルをアセンブリに埋め込むには、ファイルのプロパティ項目の [ ビルド アクション ] を、 " 埋め込まれたリソース " に設定してビルドする。
埋め込まれたリソースを利用するには、以下のようにリフレクションを利用する。
埋め込まれたリソース"Hoge.txt"を取得する例
using System;
using System.IO;
using System.Reflection;
namespace YokoKen.Sample
{
static class Program
{
void Main()
{
string outputText;
Assembly thisAssembly = Assembly.GetExecutingAssembly();
using (Stream resourceStream = thisAssembly.GetManifestResourceStream("YokoKen.Sample.Hoge.txt"))
{
using (StreamReader resourceReader = new StreamReader(resourceStream))
{
outputText = resourceReader.ReadToEnd();
}
}
Console.WriteLine(outputText);
Console.ReadLine();
}
}
}
注意すべきは、AssemblyオブジェクトのGetManifestResourceStreamメソッドに渡すファイル名には、名前空間を含める必要があるということだ。この名前空間はプロジェクトのプロパティ項目の [ 規定の名前空間 ] に設定してある名前空間(サブディレクトリに配置した場合、これにディレクトリ階層が加えられた名前空間)である。




