1

Is there a way to generate a compiler warning if a method is used outside of a class, but not if it is used inside the class?

Reason: class has some basic behaviour that can be done ahead of time in all but a few method overload circumstances. The idea was to say, it's fine to do this, but you need to be aware of a few things about how this class works.

sgtz
  • 8,849
  • 9
  • 51
  • 91
  • 3
    If it's never meant to be called outside of the class why not just make it private? Or under what circumstances is it OK to call it outside? (I can't figure out your second paragraph, you may have to explain it more specifically or with code.) – BoltClock Aug 11 '11 at 09:50
  • 2
    Some thing like Depricated attirbute? – Zenwalker Aug 11 '11 at 09:51
  • 1
    Compiler warnings are not API documentation – MattDavey Aug 11 '11 at 09:59
  • @BoltClock it's okay to use the method because this was the way the class used to work before I realised that the class could be simplified in 90% of cases. However, it makes sense to keep the more raw functionality available. I thought that a warning might be a nice way of saying refer to documentation. – sgtz Aug 11 '11 at 10:59
  • @MattDavey see comment to BoltClock. It seemed like a decent way of saying be careful of X, see documentation. – sgtz Aug 11 '11 at 11:01

3 Answers3

4

If a method is only meant to be called within a class, make it private.

If you try to call it externally, this will cause compilation to fail with an error (not a warning).

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • +1: All warnings are errors. There's no such thing as a "warning" in the sense that "this may be wrong, but go ahead and deploy this to production anyway." – Bob Kaufman May 24 '12 at 18:29
  • Is there a way to achieve this on a property getter/setter only? – Shimmy Weitzhandler Apr 18 '17 at 23:40
  • @Shimmy - you can make the property private. – Oded Apr 19 '17 at 07:51
  • @Oded, in my case I'm using EF and I need to keep the property public so EF can load data in it, but I don't want to allow direct setting access, a warning would have been great. – Shimmy Weitzhandler Apr 20 '17 at 00:01
  • @Shimmy - outside of marking a member as obsolete (yuck), there wouldn't be a way to get a warning (and the warning you would get for that wouldn't be right). You might be able to do something with a custom [roslyn analyzer](https://msdn.microsoft.com/en-us/library/mt162308.aspx) (sometihng that looks for a custom attribute on a property, checks who is accessing it and issuing a warning for those accesses). – Oded Apr 20 '17 at 08:34
  • Agree it's yuck. But that's the only solution if you have a bunch of code with only few properties like that. You wouldn't want waste too much time on trying to hide it. I guess we'll merely warn devs in the docs. I'd even throw an exception if the writer isn't EF, but that's also yuck. – Shimmy Weitzhandler Apr 20 '17 at 20:51
4

One approach is to use the #pragma directive.

In your class with the 'raw' method, add the following line at the top:

#pragma warning disable 0612

Mark your 'raw' method with the [Obsolete()] attribute.

So long as your class is the only class declared in the file with the pragma directive, any call to the raw method within that class will not raise a compiler warning. Calls made from other classes (files) will still raise a compiler warning similar to this:

c:\projects\ConsoleApplication1\ConsoleApplication1\Program.cs(13,13): warning CS0612: 'ConsoleApplication1.Class1.Test()' is obsolete

e.g.

Program.cs

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Class1 c = new Class1();
            c.Test(); // call the raw method but with a compiler warning
        }
    }
}

Class1.cs

#pragma warning disable 0612

using System;

namespace ConsoleApplication1
{
    class Class1
    {
        [Obsolete()]
        public void Test()
        {
             // the 'raw' method
        }

        private void CallTest()
        {
            Test(); // call the raw method without a compiler warning
        }
    }
}

When compiled, I get one compiler warning in Program.cs, not in Class1.cs

Health warning - this will suspend compiler warnings for calls made within Class1 to obsolete methods in other classes as well.

Neil Moss
  • 6,598
  • 2
  • 26
  • 42
  • thanks. maybe put this in the answer. I after searching on keywords in your answer. http://stackoverflow.com/questions/968293/c-selectively-suppress-custom-obsolete-warnings – sgtz Aug 11 '11 at 12:13
  • Upvote this answer. And disabling 0612 or 0618 is depend on the way using [Obsolete] https://stackoverflow.com/questions/10359117/what-is-the-difference-between-warning-codes-cs0618-and-cs0612 – Khang Dinh Hoang May 18 '20 at 05:00
0

You can use [Obsolete] attribute, but it will show warning every time whether you use it within class or outside class. In obsolete message you can explain other details.

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
PM.
  • 1,735
  • 1
  • 30
  • 38