2010-06-19 59 views
2

在SafeHandles的.Net security blog article中,它提到您需要將ReliabilityContract屬性應用於關閉句柄的本機方法的簽名。從SafeHandle繼承時,我們是否應該重新應用ReliabilityContract屬性?

當我們自SafeHandle繼承我們必須聲明一個構造函數,ReleaseHandle方法和IsInvalid屬性,所有這些都在ReliabilityContract在基類應用(I用反射來看看的SafeHandle):

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
protected SafeHandle(IntPtr invalidHandleValue, bool ownsHandle); 

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
protected abstract bool ReleaseHandle(); 

public abstract bool IsInvalid { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get; } 

ReliabilityContract有its inherited property set to false - 我認爲這意味着我們重寫的方法將不再具有該屬性 - 那麼,我們是否需要重新應用該屬性?

+2

您承諾您已經測試了代碼,證實它不會破壞依賴關鍵終結器的自定義CLR主機的狀態。你是否?如果你實際上沒有在這樣的主機上運行(SQL Server,真的),那麼它並不重要。 – 2011-10-29 12:38:34

+0

昨天在同一個主題上遇到了一些困難,我想補充一下:SafeHandle的源代碼(根據本文的寫作時間)聲明:*您從ReleaseHandle()調用的每個方法*(而不僅僅是關閉句柄的本地方法)應該具有'ReliabilityContract'。請注意,句柄不一定*通過本地方法關閉;但即使通過託管方法關閉它們,託管方法也應該具有'ReliabilityContract'。 – Binarus 2017-02-09 13:58:24

回答

2

是的,您必須重新應用屬性,因爲ReliabilityContract將其繼承的屬性設置爲false,這意味着派生類中的方法不會應用該屬性。

看看下面的代碼。如果將Inherited命名參數設置爲false,則派生類中的Method1不具有應用的屬性。之後,將相同的參數(繼承)設置爲true並再次運行。

[AttributeUsage(AttributeTargets.Method, Inherited=false)] 
public class MyAttribute : Attribute { } 

class BaseClass 
{ 
    [My] // MyAttribute applied to base class 
    public virtual void Method1() { } 
} 

class DerivatedClass : BaseClass 
{ 
    // MyAttribute not applied to derivate class 
    public override void Method1() { } 
} 

public class Program 
{ 
    static void Main(string[] args) 
    { 
     var attributes = typeof(DerivatedClass) 
      .GetMethod("Method1") 
      .GetCustomAttributes(true); 

     foreach (var attr in attributes) 
     { 
      Console.Write(attr.ToString()); 
     } 
    } 
} 
相關問題