Detecting unused methods in C#

01/27/08

Permalink 08:43:37 pm, by truewill Email , 325 words, 3035 views   English (US)
Categories: Tips, Testing, Agile, C#, Books

Detecting unused methods in C#

In Extreme Programming Adventures in C#, Ron Jeffries mentions that Microsoft Visual Studio won’t inform him when a public method is unreferenced. This is true, but there’s a workaround.

Even with Warning level 4 and with Treat warnings as errors set to All, VS won’t tell you this. (Side note: Setting Treat warnings as errors in the project properties is one of the first things I do on a new project.) It will tell you about unused variables and fields, though.

FxCop does report “Avoid uncalled private code” for private methods. With public methods on public classes, though, some unknown assembly might call them. Clearly we want to know about uncalled code for internal classes. If we make a class internal, FxCop will report on uncalled public methods.

Great! But - how do we test our classes? We want our unit tests in a separate assembly, and other assemblies don’t have access to internal classes. Or at least, they don’t unless they’re friend assemblies. C# lets you specify [assembly: InternalsVisibleTo("UnitTests")] in AssemblyInfo.cs, where UnitTests is the name of another assembly. Now the unit tests can access the internal classes.

There’s a catch, though. As soon as you add that directive, FxCop recognizes that the classes are externally visible. As such, it no longer detects uncalled code. A workaround is to comment out the assembly directive, build, then run FxCop to check for uncalled code. I’m not aware of a way to automate this.

My test code follows. The public static class was necessary to let FxCop know that the internal class was actually instantiated and the Called method called; it would not be needed in real-world code.

namespace UnusedMethodsTest
{
    public static class Foo
    {
        public static void DoIt()
        {
            Class1 c = new Class1();
            c.Called();
        }
    }

    internal class Class1
    {
        public int Called()
        {
            return _Value;
        }

        public void NeverCalled()
        {
            _Value++;
        }

        private int _Value = 4;
    }
}

In AssemblyInfo.cs:

// [assembly: InternalsVisibleTo("UnitTests")]

See also “Friend Assemblies” in the VS Help (C# Programming Guide).

Comments, Pingbacks:

Comment from: Srikanth [Visitor] Email
This is very much useful to me. Is there any procedure to call private classes also.
PermalinkPermalink 06/12/08 @ 06:31
Comment from: truewill [Member] Email · http://www.truewill.net
Hi Srikanth,

I haven't tried this, but supposedly you can via reflection. I found this article:

http://www.capdes.com/2007/02/example_call_private_method_w.html

In general, though, unit testing private methods is not considered good practice. If the private methods do enough to warrant testing, consider refactoring that functionality into separate (public or internal) classes.
PermalinkPermalink 06/12/08 @ 12:42

Leave a comment:

Your email address will not be displayed on this site.
Your URL will be displayed.

Allowed XHTML tags: <p, ul, ol, li, dl, dt, dd, address, blockquote, ins, del, span, bdo, br, em, strong, dfn, code, samp, kdb, var, cite, abbr, acronym, q, sub, sup, tt, i, b, big, small>
(Line breaks become <br />)
(Set cookies for name, email and url)
(Allow users to contact you through a message form (your email will NOT be displayed.))
The name truewill is composed of two other words. What is the SECOND word?

Development Central

Development Central is the blog of Bill Sorensen, a professional software developer. Much of this will relate to C#, .NET, and OOP in general.

Disclaimer
These postings are provided "AS IS" with no warranties and confer no rights.

Search

Categories

Linkblog

b2evolution

contributors

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 2

powered by b2evolution free blog software