开发者

Why use private members then use public properties to set them?

Seen a few examples of code where this happens:

public class Foo
{
    string[] m_workID;
    public string[] WorkID
    {
        get
        {
            return m_w开发者_开发知识库orkID;
        }
        private set
        {
            m_workID = value;
        }
    }
}

What's the point of this? Since the use m_workID unnescessary.


In general, the point is to separate implementation (the field) from API (the property).

Later on you can, should you wish, put logic, logging etc in the property without breaking either source or binary compatibility - but more importantly you're saying what your type is willing to do, rather than how it's going to do it.

I have an article giving more benefits of using properties instead of public fields.

In C# 3 you can make all of this a lot simpler with automatically implemented properties:

public class Foo
{
    public string[] WorkID { get; private set; }
}

At that point you still have a public getter and a private setter, but the backing field (and property implementation) is generated for you behind the scenes. At any point you can change this to a "normal" fully-implemented property with a backing field, and you'll still have binary and source compatibility. (Compatibility of serialized objects is a different matter, mind you.)

Additionally, in this case you can't mirror the behaviour you want (the ability to read the value publicly but write it privately) with a field - you could have a readonly field, but then you could only write to it within the constructor. Personally I wish there were a similar shorthand for this:

public class Foo
{
    private readonly int id;
    public int Id { get { return id; } }

    ...
}

as I like immutable types, but that's a different matter.

In another different matter, it's generally not a good idea to expose arrays like this anyway - even though callers can't change which array WorkID refers to, they can change the contents of the array, which is probably not what you want.

In the example you've given you could get away without the property setter, just setting the field directly within the same class, but it would mean that if you ever wanted to add logging etc you'd have to find all those writes.


A property by itself doesn't provide anywhere to put the data - you need the field (m_workID) for storage, but it entirely correct to hide that behind a property for many, many reasons. In C# 3.0 you can reduce this to:

 public string[] WorkID {get; private set;}

Which will do much of the same. Note that exposing an array itself may be problematic, as there is no mechanism for protecting data in an array - at least with an IList<string> you could (if needed) add extra code to sanity check things, or could make it immutable. I'm not saying this needs fixing, but it is something to watch.


In addition to the Object Oriented philosophy of data encapsulation, it helps when you need to do something every time your property is read/write. You can have to perform a log, a validation, or any another method call later in your development.

If your property is public, you'll have to look around all your code to find and modify your code. And what if your code is used as a library by someone else ?

If your property is private with appropriate get/set methods, then you change the get/set and that's all.


You can use C# 3.0 auto properties feature to save time typing:

public class Foo
{
    public string[] WorkID
    {
        get; private set;
    }
}

In addition properties gives you lot of advantages in comparison to fields:

  • properties can be virtual

  • properties hide implementation details (not all properties are just trivial variable accessors)

  • properties can contain validation and logging code and raise change events

  • interfaces cannot contains fields but properties


A lot of times you only want to provide read access to a field. By using a property you can provide this access. As you mention you may want to perform operations before the field is accessed (lazy loading, e.g.). You have a lot of code in there that just isn't necessary anymore unless you're still working in .Net 2.0-.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜