17

Ok, I know that property overloading is not supported in C# - most of the references explain it by citing the single-method-different-returntype problem. However, what about setters? I'd like to directly assign a value as either a string or object, but only return as a string.

Like this:

    public string FieldIdList
    {
        get { return fieldIdList.ToString(); }
        set { fieldIdList = new FieldIdList(value); }
    }

    public FieldIdList FieldIdList 
    {
        set { fieldIdList = value; }
    }
    private FieldIdList fieldIdList;

Why wouldn't this be allowed? I've also seen that "properties" simply create getter/setter functions on compile. Would it be possible to create my own? Something like:

    public void set_FieldIdList(FieldIdList value)
    {
        fieldIdList = value;
    }

That would do the same thing. Thoughts?

1
  • 2
    I was bitten by the same problem, and I'm quite disappointed by this limitation of the language (for I see no reason for it). Strangely enough, properties are the cool C# language feature I miss in C++, and there, I find them sorely lacking.
    – paercebal
    Commented Jul 9, 2011 at 23:30

5 Answers 5

8

Properties are in fact a pair of get/set methods (one of which may be left out), but the property itself has additional metadata which makes it a property in the first place instead of just two methods.

Because the property signature remains invalid as per only-different-by-return-type, even if you only have a setter. If you need this, don't use a property; set-only properties aren't a good thing anyways.

6
  • 1
    So, the compiler creates a signature for a pair of methods, and that's what prevents additional overloads? Does this just make Properties a convenience or is there more to it? What additional data makes it a property?
    – end-user
    Commented Apr 9, 2010 at 16:20
  • Not exactly. Just as you can't have two variables of a different type with the same name, you cannot have two properties with a different type and the same name. The problems are the same, the compiler would not know which variable or property to use in which situation. Therefore, even if you chose your accessors so that the get/set methods don't generate a conflict, the compiler cannot allow you to use the same property name multiple times if the signature is the same (note that you may have several indexer properties, because in this case the signature does differ, even with the same name).
    – Lucero
    Commented Apr 11, 2010 at 10:07
  • 3
    @Lucero: And if the type of the property was imposed by the type of the return of the get method? In that case, we could have setters of many types, the body of the set method handling the necessary conversion. There is no confusion for the compiler, and we still get strong-typing as the set method is chosen as per method overload rules, instead of needing to use an object property accepting anything to resolve the questioner's problem (and mine, as it is).
    – paercebal
    Commented Jul 9, 2011 at 23:18
  • @paercebal, that's all nice, but that would cause other problems, such as how to deal with virtual and abstract properties etc. Fact is, a property is a construct which allows up to one getter and one setter each with a clearly defined signature. If that doesn't fit, then by all means don't use a property but revert to a bunch ob setter methods, which you can then overload.
    – Lucero
    Commented Jul 11, 2011 at 11:00
  • @Lucero: how to deal with virtual and abstract properties? As getter and setters are methods, their virtual-ness of abstract-ness shouldn't be a problem. a property is a construct which allows up to one getter and one setter each with a clearly defined signature : My point exactly. I believe the fact a setter's value type being limited to the getter's return type is a design decision (good or bad, it doesn't matter), not a technical limitation. The next question being: Wouldn't it be easy to add to the C# language the possibility of overloading the setter?
    – paercebal
    Commented Jul 12, 2011 at 11:35
1

One approach (you may argue amongst yourselves as to whether this is a good design choice or not) is to add a second property, which accesses the data in a different form.

However, as it is going to be parsing the string (doing significant work), it would be better not to use a property for this, but to add methods that allow you to get/set the data in a string form.

I'd go for fieldIdList providing ToString() and TryParse() interfaces - then if you need it as a string, you'd call myObject.FieldIdList.ToString() etc. This encapsulates everything tidily, allows you to convert to/from string formats anywhere in your code rather than only when accessing FieldIdLists as a member of some other class, and makes the client code really clear and easy to understand.

5
  • 1
    The string overload is an example, not the general case. The questioner wants to provide an overload to the set method of a property, for type A and for B, whatever their types. Let's say their "conversion" to the property's true underlying type is not "significant work". Then using properties would be a good, natural solution in C# IMHO.
    – paercebal
    Commented Jul 9, 2011 at 23:24
  • @paercebal: As a best-practice, properties should have trivial implementations with no side effects - programmers should be able to treat a property as if it were a simple member variable (that is, assume that setting it will be quick/efficient, lossless, and not raise events or exceptions). In any other case it is better practice to implement it as a method. Overloads of a property mean that the property is a non-trivial implementation, and that some level of complexity is being hidden. This won't always be bad, but frequently is. Commented Jul 10, 2011 at 11:07
  • I understand the "best-practice" excuse, but to have it enforced by the compiler seems useless and overkill because: 1. bad programmers will always write bad properties no matter how much compiler limitation involved 2. It limits good programers from doing something that would be right. . . 3. Am I the only one to find it amusing/contradictory the fact a property can't be overloaded, but still can be overriden (by making it virtual)?
    – paercebal
    Commented Jul 10, 2011 at 15:56
  • Is it a case of choosing to "enforce" this in the compiler, or is it that it is simply not a useful enough feature to justify the cost of implementing support for it in the compiler? We can't overload a method on return type alone, so why should it seem unusual that this also applies to properties? Commented Jul 10, 2011 at 20:34
  • 3
    We can't overload a method on return type alone : True, for the getter method, but out-of-topic for the setter method, which returns a void, and has a typed parameter. According the the C# Langage Specification, a property is not a storage location, but a set of accessor methods: the real name of the getter/setter of a property P is defined as T get_P() and void set_P(T value), so why couldn't we add an overloaded setter of prototype set_P(T2 value)?. All in all, the overload of the setter seems to me to be a simple syntactic issue, not a technical or a semantic one.
    – paercebal
    Commented Jul 10, 2011 at 21:59
0

If you want to be able to set a property as either a string or an object then you would just use object as the type of the property, since it's the base class (you can pass a string to a property that accepts an object). This doesn't seem particularly good design decision, but it can be done. Perhaps you need to explain further what you are trying to achieve?

2
  • 6
    The questioner was quite clear: He wants to provide method overloads for the set method. This is as legitimate as writing multiple overloaded SetField(Field field) and SetField(string field) methods.
    – paercebal
    Commented Jul 9, 2011 at 23:20
  • @DanDiplo Using object is not really of help, as the OP wants to accept only two types, a String, and the custom FieldIdList.
    – Marcel
    Commented Mar 19, 2014 at 8:51
0

You cannot overload C# properties as of C#7.

However, a redesign including your property is possible.

You can use a condition in your set block to call a private function, which can be overloaded.

public string FieldIdList
{
    get { return fieldIdList.ToString(); }
    set { fieldIdList = ChangeFieldList(value); }
}

private string ChangeFieldIdList(int i) {
    return i.ToString();
}

This example is just mean't to show a redesign consideration using private functions to be called within the set block.

-2

If you need to overload a property, consider maybe inheriting from a base class and implementing different versions of that property for the sub classes.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.