下記のサイトを見て属性について勉強しています。
http://www.atmarkit.co.jp/fdotnet/vb6tonet/vb6tonet28/vb6tonet28_01.html
ここでは、「属性とは、クラス、メソッドなど、プログラミングに使用するさまざまな構成要素に付加できる情報」とありますが
DllImport属性は、マネージアプリケーションからアンマネージコードを
呼び出せるようにできるらしく、情報の付加以上のことを行っているように思えます。
http://msdn.microsoft.com/ja-jp/library/aa984739(v=vs.71).aspx
属性とは一体何なのか?どこまでのことができるのか?
さっぱり解らなくなりました。。
<DllImport("urlmon.dll", CharSet:=CharSet.Ansi)>
Private Shared Function UrlMkSetSessionOption(ByVal dwOption As Integer,_ ByVal str As String, ByVal nLength As Integer, ByVal dwReserved As Integer) As Integer
End Function
> 情報の付加以上のことを行っているように思えます。
付加された情報が「どこで利用されるのか」が焦点となります。
属性それ自体には、情報(メタデータ)を付加するだけの役割しかありません。
重要なのは、その情報がどこで何のために利用されるかです。
AssemblyCopyrightAttribute は、.NET のアセンブリに対して
著作権情報を設定するために使われます。
http://www.atmarkit.co.jp/fdotnet/dotnettips/187asmverinfo/asmverinfo.html
ObsoleteAttribute を使うと、特定のメソッドやクラスを使ったコードを
コンパイルしたときに、警告メッセージを発したり、あるいはそもそも
コンパイルが通らないようにエラー扱いにすることができます。
http://wiki.sh4e.net/?Attribute%2FObsoleteAttribute
ConditionalAttribute を指定すると、条件付きコンパイル定数が
定義されている場合のみ、メソッドの呼び出しを行うようにすることが出来ます。
http://smdn.jp/programming/netfx/conditional/
BrowsableAttribute、CategoryAttribute、DescriptionAttribute を
プロパティやイベントに付与した場合、Visual Studio デザイナの
[プロパティ] ウィンドウに、その項目が表示されるかどうかといった
実行時には関係のない、デザイン時情報を付与することができます。
http://msdn.microsoft.com/ja-jp/library/aa302334.aspx
DebuggerDisplayAttribute、DebuggerBrowsableAttribute、DebuggerTypeProxy などは、
Visual Studio 等のデバッガに対して、変数ウィンドウでの型あるいはそのメンバの
表示形式を制御するために使われる、デバッグを行いやすくするための属性です。
http://www.atmarkit.co.jp/fdotnet/dotnettips/994debugdisp/debugdisp.html
DebuggerStepThroughAttribute を使うと、デバッグ時にステップ実行の
対象とならないようにしたり、ブレークポイントを無効にするなどの
制御を行うことができます。
http://www.atmarkit.co.jp/fdotnet/dotnettips/362stepthrough/stepthrough.html
このように、属性が与える影響というものはランタイムの動作だけには留まりません。
EXE にする以前の段階、すなわちコンパイラやプリコンパイラなどによって
解釈されるものもありますし、あるいは Visual Studio などの
開発環境/デバッガーによって利用されるものもあります。
もちろん、自分で新たな属性を利用し、それを自アプリから利用することもできます。
> DllImport属性は、マネージアプリケーションからアンマネージコードを
DllImportAttribute が付与されたメソッドをコンパイルすると、中間言語(msil)に対して
プラットフォーム呼び出しのための pinvokeimpl 属性が付与されます。
これにより、アンマネージ DLL にある API を呼び出すことが指示されます。
ただし、すべての .NET 対応言語のコンパイラがそうというわけではありません。
たとえば JScript の場合、そもそも API 呼出しに対応していないため、
DllImportAttribute を正しく処理できません。
(まぁ、System.Reflection.Emit を用いれば、JScript.NET からでも、
API を呼べないわけでは無いですけれども…)
魔界の仮面弁士様、ご回答ありがとうございます。
>EXE にする以前の段階、すなわちコンパイラやプリコンパイラなどによって
>解釈されるものもありますし、あるいは Visual Studio などの
>開発環境/デバッガーによって利用されるものもあります。
>もちろん、自分で新たな属性を利用し、それを自アプリから利用することもできます。
・コンパイラや開発環境に影響を与える属性は、自作できないのでしょうか?
(自作した属性は、コンパイラや開発環境その情報を持ってないので解釈できないと考えています)
・自作属性にメリットはありますでしょうか?プログラマの皆様は多用されているのでしょうか?
(個人的に自作属性を含んだコードは見づらいと感じますし、構造体を引数にする等して代替できると考えています)
> ・コンパイラや開発環境に影響を与える属性は、自作できないのでしょうか?
先述したように、既存の属性を使って開発環境やコンパイラなどに
影響を与えることならばできます。ですが、仰っている内容からすると
それとは手段と目的が逆であり、独自の属性を解釈させるように
開発環境をカスタマイズするという話になっているように思えます。
そもそも既存のコンパイラに手を加えることはできないので…強いて言えば
コンパイラそのものを自作する、という話になってくるでしょうね。
属性とは直接関係無いですが、関連しそうな話としてはこのあたり。
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=9631
一方 Visual Studio 側についてですが…通常は、VS の動作をカスタマイズ
する場合に「新たに属性を自作する」ことはしません。属性も一応使われますが、
それは「追加した独自機能を、既存の属性を用いて知らせる」形で行われます。
これはたとえば、型コンバータや型エディタのカスタマイズなどが該当します。
http://msdn.microsoft.com/ja-jp/library/aa302326.aspx
http://msdn.microsoft.com/ja-jp/library/aa302334.aspx
あるいはいっそ、開発環境そのものを自作する方向ですかね。実際、
オープンソースの.NET総合開発環境である「SharpDevelop」などは
C# で作成されているわけですし。
> ・自作属性にメリットはありますでしょうか?
自作ではないですが、有名どころとしては NUnit や log4net などで
属性が使われていたりしますね。
> プログラマの皆様は多用されているのでしょうか?
大抵の場合は .NET Framework にすでに用意されている属性だけで、
十分なので、多用というほどではないのですが…一応、
永続化のためのメタデータとして使ったことならばあります。
構造体やクラスから固定長データやバイナリレコードを作成するにあたり、
テキスト列の長さ・数値桁数・チェックデジットの有無などといった情報を、
独自の属性を使って指示するとか。(VBFixedStringAttribute みたいなものです)
魔界の仮面弁士様、ご回答ありがとうございます。
属性についての疑問点が全て解決しました。
本当にありがとうございました!