In C#, how do I keep certain method calls out of the codebase entirely?

后端 未结 6 1042
迷失自我
迷失自我 2021-01-01 23:54

I\'m trying to get rid of all DateTime.Now method calls and replace them with my own GetNow() method, which may sometimes return a fixed date for t

相关标签:
6条回答
  • 2021-01-02 00:18

    You could use Moles in your tests to provide your own DateTime.Now when required, without the need to modify any existing code that calls it.

    Another option might be to modify the assembly after compilation to call something else. (Perhaps, use Mono.Cecil to rewrite the IL, and add a command to the post-build in VS to run it.)

    You could perhaps grab the Mono source and build yourself a custom mscorlib with the function removed.

    0 讨论(0)
  • 2021-01-02 00:29

    There's no real way to enforce something like this.

    The closest you're going to come is making a custom FxCop rule or custom Visual Studio Code Analysis rule to error/warn on calls to DateTime.Now.

    0 讨论(0)
  • 2021-01-02 00:36

    Firstly, DateTime.Now is a property.
    That means you don't need to put parenthesis after call.

    Secondly, if by testing purposes you mean a framework like NUnit, you might want to check out Microsoft Moles which allows you to substitute any static method call with your own custom implementation while testing. Heck, it's cool:

    [Test]
    [ExpectedException (typeof (Y2KBugException))]
    public void TestY2KBug ()
    {
        MDateTime.NowGet = () => new DateTime (2001, 1, 1);
        Bomb.DetonateIfY2K ();
    }
    
    
    public static class Bomb {
        public static void DetonateIfY2K ()
        {
            if (DateTime.Now == new DateTime (2001, 1, 1))
                throw new Y2KBugException (); // take cover!
        }
    }
    
    0 讨论(0)
  • 2021-01-02 00:40

    I don't think that this is possible. What you are actually trying to do is override DateTime's struct functionality.

    The only way I can think of is just to go with a custom class that will wrap common functionality of DateTime and offer different functionality on demand...

    0 讨论(0)
  • 2021-01-02 00:42

    With NDepend it is very easy to write this rule:

    // <Name>Forbid DateTime.Now, use xxx.GetNow() instead</Name>
    WARN IF Count > 0 IN 
    SELECT METHODS WHERE 
    IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()"
    

    Notice:

    • The prefix WARN IF Count > 0 IN that transforms the CQL query into a rule
    • The way the property is referenced through the string System.DateTime.get_Now()
    • The prefix OPTIONAL that means "Don't emit a compilation error if the property get_Now is not found". This makes sense since if your code doesn't use anymore get_Now(), it is not anymore referenced from NDepend analysis.

    Also, to generate the original query...

    SELECT METHODS WHERE 
    IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()"
    

    ...just right-click DateTime.get_Now() and choose Select methods ... that are directly using me

    enter image description here

    0 讨论(0)
  • 2021-01-02 00:42

    One approach might be to add a pre-commit hook to your source control repository of choice to look for DateTime.Now and abort the check-in if you find the offending string. It's not foolproof and it might be annoying to your colleagues but it should help keep it out of the codebase.

    0 讨论(0)
提交回复
热议问题