views:

112

answers:

1

Hi,

I would like to ensure that a method (actually a constructor in my case) is never called explicitly from code. It should only be called through reflection at runtime. To do that, I would like to apply an attribute on the method that would generate a compiler error if the method is called, something like :

[NotCallable("This method mustn't be called from code")]
public void MyMethod()
{
}

I know that I could make the method private, but in that case I wouldn't be able to call it through reflection in a partial trust context...

For completeness, here's more details about why I need to do that :

I'm implementing a reusable Singleton<T> class, based on Jon Skeet's article. Here's my code so far :

public static class Singleton<T>
{
    public static T Instance
    {
        get
        {
            return LazyInitializer._instance;
        }
    }

    private class LazyInitializer
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static LazyInitializer()
        {
            Debug.WriteLine(string.Format("Initializing singleton instance of type '{0}'", typeof(T).FullName));
        }

        internal static readonly T _instance = (T)Activator.CreateInstance(typeof(T), true);
    }
}

(Note the way I create the T instance using Activator.CreateInstance)

I can then use it with a class like that :

private class Foo
{
    protected Foo()
    {
    }

    public string Bar { get; private set; }
}

And call Singleton<Foo>.Instance to access the instance.

In partial trust, it won't work because the Foo constructor is not public. But if I make it public, nothing will prevent calling it explicitly from code... I know I could apply the ObsoleteAttribute on the Foo constructor, but it will only generate a warning, and many people just ignore warnings.

So, is there an attribute similar to ObsoleteAttribute that would generate an error instead of a warning ?

Any suggestion would be appreciated

+4  A: 

You can use the ObsoleteAttribute constructor that takes a boolean with which you can indicate that calling the method is a compilation error:

[Obsolete("Don't use this", true)]

However, if I were you, I'd reconsider my design, as doing this isn't a sign of a well-designed API.

Mark Seemann
Oh, I had never noticed this parameter... thanks ! Regarding the design, I agree that it's not ideal. The "normal" way of doing it would be to declare the constructor non-public. The workaround using ObsoleteAttribute would be used only if the code is going to run in partial trust.
Thomas Levesque