2011-06-17 4 views
13

私はカスタムセキュリティ属性を書き込み、奇妙なコンパイラの動作を持って...私は同じファイルで属性を使用している場合は、デフォルトのパラメータ値てる正常に動作します:これはC#4.0コンパイラのオプションパラメータバグですか?

using System.Security.Permissions; 

[System.Serializable] 
sealed class FooAttribute : CodeAccessSecurityAttribute { 
    public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { } 
    public override System.Security.IPermission CreatePermission() { return null; } 
} 

[Foo] class Program { 
    static void Main(string[] args) { } 
} 

しかし、私は、コードを分離しています上記のような2つのファイルに - ファイル1:

using System.Security.Permissions; 

[System.Serializable] 
sealed class FooAttribute : CodeAccessSecurityAttribute { 
    public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { } 
    public override System.Security.IPermission CreatePermission() { return null; } 
} 

とファイル2:私は、コンパイラのエラーを持っている

[Foo] class Program { 
    static void Main(string[] args) { } 
} 

Error: 'FooAttribute' does not contain a constructor that takes 0 arguments

これは、CodeAccessSecurityAttribute相続でのみ発生は非常に奇妙に見える...

+2

ソース内のFooAttributeとDebugCallTraceAttributeの間のエラーメッセージの関係は何ですか? –

+2

第1のスニペットには 'SecurityAttribute'、第2のスニペットには' CodeAccessSecurityAttribute'がありますか?有効な最小限のテストケースでは、これらが同じである必要があります。 (たとえば、この変更に関連するのか、それとも2つのファイルにあるのか、その両方に関係していますか?) –

+0

申し訳ありませんが、モスクワの3amです。すべてのスニペットミスは修正されました – ControlFlow

答えて

13

だから私は、正確な答えを持っていないが、私は限り私はそれに探して可能性としてそれを取りました。

.permissionset demand = {class 'ConsoleApplication1.FooAttribute, ConsoleApplication1, Version=1.0.0.0, Culture=neutral' = {}} 

ときSecurityAttributeそれからFoo継承:私はそれがCodeAccessSecurityAttributeから継承したときにFoo属性を適用するとき、それはこのようになります生成され、あなたがCodeAccessSecurityAttributeなくSecurityAttribute.から継承したときに、それはなぜ起こるかあなたはILを見れば、私は理解して考えます

.custom instance void ConsoleApplication1.FooAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = (01 00 02 00 00 00 00 00) 

明らかに、CodeAccessSecurityAttributeは、属性を適用して生成されたILを大幅に変更します。

.permissionset demand = {class 'ConsoleApplication1.FooAttribute, ConsoleApplication1, Version=1.0.0.0, Culture=neutral' = {}} 

そのを私たちはしなかったとき、それがあったのと同じ:私たちは

[Foo(SecurityAction.Demand)] 

を次のようにFooの宣言は次のようであることを変更した場合、我々は、以下のILを得るより多くのILを見てみると

オプションのパラメーターを指定します。さらに私たちは、このようなクラス内のファイルを再配置することによって、それを引き起こすことができるだけでなく、属性と別のファイルにProgramクラスを分割することによって、エラーが発生する可能性があります:

[Foo] 
class Program 
{ 

    static void Main(string[] args) {} 


} 

[System.Serializable] 
sealed class FooAttribute : CodeAccessSecurityAttribute 
{ 
    public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { } 
    public override System.Security.IPermission CreatePermission() { return null; } 
} 

さらに興味深いのは、私たちがクラスで次の操作を実行している場合OtherおよびOther2はエラーを示しますが、Programはエラーを示していません。ファイルにFooの前に来るだけのクラスが、これは私に言ってどのようなエラー

[Foo] 
class Other 
{ 

} 

[Foo] 
class Other2 
{ 
} 

[System.Serializable] 
sealed class FooAttribute : CodeAccessSecurityAttribute 
{ 
     public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { } 
     public override System.Security.IPermission CreatePermission() { return null; }  } 

[Foo] 
class Program 
{ 

    static void Main(string[] args) {} 
} 

を持つことになり、問題がどこかにビルドプロセスであるということです。コードアクセスセキュリティが正確な問題が何であるかを指摘するためにどのように機能するかは十分に分かりません。 CodeAccessSecurityAttributesを見て、コードにSecurityActionを適用しようとしている処理の一部がなければなりません。私はそれがアセンブリのための何らかの種類のメタデータを構築すると仮定します。プログラムクラスにすでに渡された後でなければ、オプションのパラメータが表示されないように、順序付けられた方法でこれを行わなければなりません。次に、ビルドプロセス中に何らかの方法でそのメタデータを使用する必要があります。これが失敗の原因です。それ以上の詳細については、コンパイラを知っている誰か、つまりEricがそのことを明らかにしてくれることを願ってください。私はconnect.microsoft.comに提出したいと思うコメントの1つとして提出したいものがあります。

+1

+1良い分析のために私から。 – Jehof

+0

** **すべての**バグレポートだけが十分に研究され、書かれていれば! –

関連する問題