>>74にもあるんだけど、アトリビュートってどういう時に使うものなの?
.NETのAPI見てるとかなりえげつないことやってるけど、
どうしてあんなことができるのか不思議だ。。。
>>304 Attributeは大きく分けて2種類あるよん。
1つはCustom Attributeといって、exeとかdllにデータを直接埋め込んじゃうやつ。
んで、コンテナ側でリフレクションを使ってそのデータを吸い上げて、
そこで特殊な処理を行なう...といった感じ。
だから、「えげつないこと」は実はコンテナ側がやってる。
もう1つはContext Attributeといって、こちらは処理のインターセプトができる。
例えば、インスタンス起動とかメソッド実行の前後のタイミングを拾える(らしい)ので、
そこに特殊な処理を割り込ませることができる。
これはAttributeの実装側で「えげつないこと」をやることになると思う。
そういえば、漏れも前に「メソッドの終わりに来たら強制ガベコレ起動」なんていうのを
お遊びで作ったことがあるけど、下手すると本当に何でもありになるよ。(藁
...あまり答えになってないけど、こんなんでいい?
>>305 何となくわかりました。
アトリビュートそのものに仕掛けを作ったり、受け側に仕掛けを作ったり
っちゅうことですね。
>「メソッドの終わりに来たら強制ガベコレ起動」
ソースあぷきぼーん
>>306 別にいいけど、97%パクリソースだよ。(藁
元ネタは、Don Box先生の「UnwindScope Service」ね。
http://www.develop.com/dbox/dotnet/unwind/ // ForceGC.cs
using System;
using System.Runtime.Remoting;
namespace ForceGC
{
[ AttributeUsage(AttributeTargets.Class) ]
public class ForceGCAttribute : ContextAttribute
{
public ForceGCAttribute() : base("ForceGCAttribute") {
}
public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg) {
ctorMsg.ContextProperties.Add(new ForceGCProperty());
}
public override bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg) {
return false;
}
}
class ForceGCProperty : IContextProperty, IContributeObjectSink
{
public ForceGCProperty() {
}
public string Name {
get { return "ForceGC"; }
}
public void Freeze(Context newCtx) {
}
public bool IsNewContextOK(Context newCtx) {
return true;
}
public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink) {
return new ForceGCObjectSink(nextSink, this);
}
}
class ForceGCObjectSink : IMessageSink
{
IMessageSink nextSink;
ForceGCProperty prop;
public ForceGCObjectSink(IMessageSink nextSink, ForceGCProperty prop) {
this.nextSink = nextSink;
this.prop = prop;
}
public IMessageSink NextSink {
get { return nextSink; }
}
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) {
return null;
}
public IMessage SyncProcessMessage(IMessage msg) {
IMessage result = nextSink.SyncProcessMessage(msg);
Console.WriteLine("--- GC ---");
GC.Collect();
return result;
}
}
}
// csc /t:library ForceGC.cs
使用例。[ ForceGC ]をコメントアウトしてみて、違いを比べてちょ。
// Test.cs
using System;
using ForceGC;
// テストクラス。作成時と破棄時にメッセージを出すだけ。
class Hoge
{
string name;
public Hoge(string name) {
this.name = name;
Console.WriteLine("{0} Created.", name);
}
~Hoge() {
Console.WriteLine("{0} Destroyed.", name);
}
}
[ ForceGC ]
class Container : ContextBoundObject
{
public void Invoke1() {
Hoge h1 = new Hoge("AAA");
Hoge h2 = new Hoge("BBB");
} // ← ここでGC起動。
public void Invoke2() {
Hoge h3 = new Hoge("CCC");
} // ← ここでGC起動。
}
class EntryPoint
{
public static void Main() {
GC.RequestFinalizeOnShutdown();
Container c = new Container();
c.Invoke1();
c.Invoke2();
Hoge h4 = new Hoge("DDD");
}
}
// csc /r:ForceGC.dll Test.cs
一応言っておくけど、
>>307-309 はお遊びレベルで作っただけで、
決して実用品じゃないからね。
だからツッコミは勘弁。
>>307-310
うおお。ほんとにありがとうございます〜。
確かにガベコレが動いてる。不思議だ。。。