views:

112

answers:

2

In the following code:

public class MovieRepository : IMovieRepository
{
    private readonly IHtmlDownloader _downloader;

    public MovieRepository(IHtmlDownloader downloader)
    {
        _downloader = downloader;
    }

    public Movie FindMovieById(string id)
    {
        var idUri = ...build URI...;

        var html = _downloader.DownloadHtml(idUri);

        return ...parse ID HTML...;
    }

    public Movie FindMovieByTitle(string title)
    {
        var titleUri = ...build URI...;

        var html = _downloader.DownloadHtml(titleUri);

        return ...parse title HTML...;
    }
}

I asked for something to review my code, and someone suggested this approach. My question is why is the IHtmlDownloader variable readonly?

+8  A: 

If it's private and readonly, the benefit is that you can't inadvertently change it from another part of that class after it is initialized. The readonly modifier ensures the variable can only be given a value during class initialization and in a constructor.

If something functionally should not change after initialization, it's always good practice to use available language constructs to enforce that.

Eric J.
Bingo. If it's readonly, it can only be set either by object initialization, or in the constructor. It's not necessary, but part of code quality is limiting the scope in which an error can occur.
Cylon Cat
Eric's answer was good but didn't make sense until Cylon said that you could only change a readonly field in the initialization and constructor. Thanks guys!
Sergio Tapia
There is an added benefit in that the compiler and the JITter can effect certain optimizations knowing the value will be fixed after construction.
Jesse C. Slicer
@Sergio: Good point, I updated the answer to make that clear.
Eric J.
+1 for advice on language constructs - I must have seen hundreds of fields that should be readonly but aren't enforced.@Jesse C. Slicer this article seems to suggest no benefit:http://dotnetperls.com/readonly-field
Adam
@Adam: The tests in that article are too simplistic. It's entirely possible that the compiler can analyze the entire program and never even call the GetValue#() functions. A look at the IL code would be needed to know if even the worst-case (regular int) has not been entirely optimized away.
Eric J.
True enough. Do you have any links covering this JIT optimisation? I'm curious - don't tend to concern myself with them too much :)
Adam
@Adam: No, the last time I seriously looked at compiler optimizations was maybe 10 years ago (and 10 year old compilers could optimize out all of those calls). These days, there's little point to it for most apps. The hardware is "fast enough" for many things, some things that require breakneck performance (e.g. games and now broader classes of numerical computing thanks to CUDA/OpenCL) have dedicated hardware, ...
Eric J.
+2  A: 

This ensures that the value of _downloader will not be changed after the constructor was executed. Fields marked as readonly can only be assigned a value from within the constructor(s) of a class.

M4N