soapergem
soapergem

Reputation: 9989

Can I initialize public properties of a class using a different type in C#?

In Java, I can have an object like this:

public class MyObject {

    private Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public void setDate(String date) {
        this.date = parseDateString(date);
    }

    private Date parseDateString(String date) {
        // do magic here
        return dateObj;
    }

}

This is nice, because I have one getter for my properties, and multiple setters. I can set the "date" property by passing in either a Date object, or a String, and let the class figure it out.

In C# it looks like things are a little different. I can do this:

public class MyObject
{
    public DateTime Date { get; set; }
}

The shorthand here is obviously optimal. However, I'm not sure if there's any built-in way to overload the setter to accept multiple types. I realize I could create a separate public method to set the value, but that would sacrifice the ability to use object initializers.

Is there any way to directly overload the setter on public properties for C#? Or is this just a language limitation, and it can't be done?

Upvotes: 23

Views: 3049

Answers (4)

Jcl
Jcl

Reputation: 28272

All other answers are correct... but if you insist, you can do it in several ways:

  1. Use a second property with just a setter:

    public string DateText { set { Date = ParseDateString(value); } }
    

    Avoid this if possible, it only adds confusion :-)

  2. Use methods instead of properties (same as you do in Java). Methods can be overloaded. This should be the most recommended way.

  3. Use a custom class (instead of DateTime) and provide implicit conversions between DateTime, string, and your class. Not recommended unless you are going to use this everywhere else.

  4. Change the property to object and provide your conversions in the setter: please don't do this

Upvotes: 22

I'm going to write a different answer and claim that

public void setDate(Date date) {
    this.date = date;
}

public void setDate(String date) {
    this.date = parseDateString(date);
}

is bad practice to begin with.

By doing the above, you are claiming that both strings and dates are valid values for Date. This is not the case - what you really want is a Date. If the user has a string and wants it converted a Date, they should be relying on the string-parsing functionality in the Date API (DateFormat.parse() in Java, DateTime.Parse() in C#), not your API.

If Date is a class defined by you and you really do want Date and string to be interchangable, you should be using implicit conversations in the Date class, not asking users of your Date class to write overloads.

Upvotes: 10

Emond
Emond

Reputation: 50672

The auto properties do not support this. So you will have to do the same as you do in Java.

Of course you could mix these as well: provide an auto property and extra set-methods to set the property using different types.

public class MyObject 
{
    public DateTime Date { get; set; }

    public void SetDate(string date) 
    {
        this.Date = DateTime.Parse(date);
    }    
}

Upvotes: 10

Mathieu Guindon
Mathieu Guindon

Reputation: 71177

Well, you're comparing apples to bananas. What you have in Java here:

public void setDate(Date date) {
    this.date = date;
}

public void setDate(String date) {
    this.date = parseDateString(date);
}

Would look like this in C#:

public void SetDate(Date date) 
{
    this.date = date;
}

public void SetDate(String date) 
{
    this.date = ParseDateString(date);
}

The only difference being the PascalCase member names and the location of the scope-opening brace.

Your Java code has overloaded methods; the above C# has overloaded methods.

AFAIK you can't overload a property setter, because:

public DateTime Date 
{ 
    get { return this.date; }
    set { this.date = value; }
}

...the type of value is determined by the type of the member, here DateTime.

So if you want method overloads, overload methods, not properties. Remember that C# properties are just syntax sugar for getter & setter methods anyway.

Upvotes: 16

Related Questions