Please enter the text to find and press Search.
Sorry

An error occurred during search results load.

Protected Private Visibility

.NET languages offer a few keywords for visibility control between assemblies, classes and members. For example, C# has public, internal, protected, protected internal and private access modifiers.

Sometimes you may need a special access level: protected private. It exists in C++ but absent in C# and VB.NET. It corresponds to FamANDAssem visibility scope in terms of .NET CLR.

This is indeed a rare requirement. Let's take a look on specific example. Suppose you have a DLL assembly written in C# that does XML serialization for some entities:

Example 5.3. Original code

using System;
using System.Xml.Serialization;

// This class is used by System.Xml.Serialization.XmlSerializer.
public class Card
{
    public string ID
    {
        get;
        set;
    }

    protected virtual void Validate()
    {
    }
}

// This class is used by System.Xml.Serialization.XmlSerializer.
public class VerticalCard : Card
{
    public int Height
    {
        get;
        set;
    }

    protected override void Validate()
    {
        if (Height <= 0)
            throw new Exception("Vertical card height should be a positive number greater than zero.");
    }
}


See that Validate method? It won't be renamed after obfuscation despite the wish of developer. But why? The answer is: because assembly is DLL, the class is public and Validate method is protected. This means that Validate method can be reached by a third-party assembly and Eazfuscator.NET leaves its name intact.

That's ok for most situations.

Still, let's imagine that one picky developer decides to rename Validate method whatever it costs. Potential workarounds are:

  • Make Validate methods private. Won't work because it wouldn't be possible to override Validate method in VerticalCard class

  • Make Card and VerticalCard classes internal. Won't work because XmlSerializer works on public classes only

  • Make Validate methods internal. Will work but will break the visibility borders inside the assembly. This may be unfeasible if you work in a team with established responsibility borders between its members

  • Make Validate methods protected private. Will perfectly work, but only in C++. C# and VB.NET have no corresponding access modifier

  • Move validation away to a separate set of classes. Will work, but it requires code refactoring. It may be risky for a large code base and thus not always suitable

So we are stuck if our code is in C# or VB.NET.

Fortunately Eazfuscator.NET can change the visibility of class members to FamANDAssem level. This is the exact same thing as protected private in C++. Having that, we can now solve the dilemma (C#):

Example 5.4. Modified code to allow family and assembly visibility for specified methods

using System;
using System.Xml.Serialization;
using System.Reflection;

// This class is used by System.Xml.Serialization.XmlSerializer.
public class Card
{
    public string ID
    {
        get;
        set;
    }

    [Obfuscation(Feature = "family and assembly visibility", Exclude = false)]
    protected virtual void Validate()
    {
    }
}

// This class is used by System.Xml.Serialization.XmlSerializer.
public class VerticalCard : Card
{
    public int Height
    {
        get;
        set;
    }

    [Obfuscation(Feature = "family and assembly visibility", Exclude = false)]
    protected override void Validate()
    {
        if (Height <= 0)
            throw new Exception("Vertical card height should be a positive number greater than zero.");
    }
}


Once that in place, Validate methods will be renamed and will no longer be visible to other assemblies.

Instructions on changing visibility to FamANDAssem level for a class member

  1. Open the source code of a class member that should have a visibility change
  2. Add a custom attribute as shown below (C#):

    using System;
    using System.Reflection;
    
    class YourClass
    {
        [Obfuscation(Feature = "family and assembly visibility", Exclude = false)]
        protected void YourMethod()
        {
            ...
        }
    }

    For Visual Basic .NET:

    Imports System
    Imports System.Reflection
    
    Class YourClass
    
        <Obfuscation(Feature:="family and assembly visibility", Exclude:=False)> 
        Protected Sub YourMethod()
            ...
        End Sub
        
    End Class
    

[Tip]Tip

If you change visibility for a virtual method then it is beneficial to ensure that the whole inheritance hierarchy has a corresponding change. This will improve renaming coverage during obfuscation.

[Tip]Tip

It may be a good idea to turn on code verification for your assembly when visibility changes are applied to ensure that generated code conforms to industrial standard.

Sorry

An error occurred during page load.
You can try again or go back.