views:

1191

answers:

5

This might be a bit of an anti-pattern, but it is possible for a property on a C# class to accept multiple values?

For example, say I have an Public int property and I always want it to return an int, but I would like to be able to have the property set by assigning a decimal, an integer or some other data type. So my question is if it possible for properties to accept multiple values?

A: 

Properties are supposed to look sort of like public fields. Create setter-methods, or do the cast/conversion in the assignment statements as opposed to in the property-setter.

Justice
A: 

No. A property has a single value. You can assign anything to it that could be assigned to a variable of the same type.

John Saunders
That is not true, you can assign it to any object that can be explicitly cast to.
Nick Berardi
@Nick Berardi: That's not accurate. Once you've cast it to a different type, you are assigning the different type!
John Saunders
@John: Agreed, don't know what Nick is smoking.
Samuel
Actually you are wrong. Take a look at how explicit casting works: http://msdn.microsoft.com/en-us/library/xhbhezf4.aspx I could set a property of type ABC to an object of type XYZ if ABC had an explicit casting to XYZ. That is what the original poster was asking about.
Nick Berardi
All the casting happens in the background, and looks as if an object of XYZ is being set to a type of ABC, which is what the poster was asking about. It doesn't help anybody to not educate the user in the process, when it is very clear what he is trying to do.
Nick Berardi
@Nick: That's nice about how explicit operators work. But that misses the point. You cannot put an integer into a long variable. It implicitly casts it to a long and is no longer an integer.
Samuel
@Samuel but that is not what the poster was asking about "say I have an Public int property and I always want it to return an int" he knows an int property can only be an int he was asking about how he can set it as something else so it transforms from another object in to an int
Nick Berardi
Also it is possible to get this working, but way more work than its worth, by modifying the actual IL code. because the set "property" is actually just a method set_MyProperty(int i) you can also tack in to the IL set_MyProperty(decimal d) to accomplish this, but the user also didn't ask about this
Nick Berardi
@Nick: In the C# and VB.NET compilers, a property can only have one type. Inserting the IL after compiling won't help you before compiling. So what John said is right.
Samuel
@Samuel well apparently the implicit casting is what the original poster was looking for, enough said...
Nick Berardi
Plus come on lomaxx is a smart guy look at his rep and badges. Your answer seemed sort of basic for his level.
Nick Berardi
@Nick: I'm not exactly fishing for rep here, but look at the subject, and look at the question. The answer to the subject is "no", which is what I answered. Property assignment is no different from variable assignment, which is also what I said.
John Saunders
@Nick: You've chosen to interpret the question according to a clarification the poster has not made. Personally, I would not downvote an answer under these circumstances. But, to each his own.
John Saunders
@John the question was very clear in what he was asking, just poorly explained, and I choose to answer what he was asking.
Nick Berardi
@Nick: I guess clear is in the eye of the beholder. In fact, why don't you edit the subject according to your understanding of what the OP was asking?
John Saunders
@John: because it is clear to me what he was asking for. also to back that up I have the accepted answer.
Nick Berardi
@Nick: Then I think you should edit the subject to match what you believe was asked. It's why I would do.
John Saunders
+1  A: 

It seems like you would have to ascertain the type at run-time. You could have the property accept an object, determine the type and take your action. You would have to throw exceptions for things you don't expect, of course. Like you say, probably not the best, but possible. :)

JP Alioto
+5  A: 

I think what you mean to ask is: How does implicit and explicit casting work for int and decimal?

You are asking about implicit casting which automatically coverts one object to another defined type. You will not be able to do this for an int and decimal because they are already defined in the framework and you are not able to reduce the scope of the decimal by casting it to an int. But if you were using that as an example for actual objects that you created you can use the implicit link above, to learn more about how this works and how to implement it.

But you can always use the convert method to convert them to the right type;

public int MyProperty { get; set; }
...
obj.MyProperty = Convert.ToInt32(32.0M);
obj.MyProperty = Convert.ToInt32(40.222D);
obj.MyProperty = Convert.ToInt32("42");
Nick Berardi
I was using ints and decimals more as an example but it is related. Essentially I just want to be able to assign multiple different types to a single property and let the property work out what to return. As you mention, implicit casting will allow this.
lomaxx
The only other thing I will add is that while implicit casting will solve the problem, it doesn't seem to sufficiently limit the scope. It will work fine for what I'm trying to do, but I can see potential problems with im(ex)plicit casting if I ever need specific rules for each cast.
lomaxx
With all that said, I still think what I'm trying to do is an anti-pattern and would probably be better served either doing it in a dynamic language where I can assign it anything I want, or rethinking what I'm doing to avoid the problem in the first place.
lomaxx
Yeah you can't really define specific rules around each cast. But the real question you should be asking is why you need specific rules. Maybe the object with different rules needs to be a different type of objects that inherits from the current one.
Nick Berardi
Completely agree Nick
lomaxx
Why are you so set on using properties?
Joe Philllips
@do3boy, couple of reasons. 1) Things like datagrids can only be databound to properties (which is what I'm doing in this specific case) 2) I'm using an ORM which assigns the values to the property. the problem is that the ORM could assign a decimal, int or long depending on the underlying source.
lomaxx
Very good to know.
Joe Philllips
+2  A: 

Edit: This method can't be used since the op is specifically bound to properties.

I do not believe this is possible with the robustness that you describe. In this case you would likely be better off using an overloaded method (polymorphism).

This is what is typically known as a setter (or mutator) and you can overload the method to accept multiple different types of parameters. Each will perform differently if you wish. The way I have them set up might not be syntactically correct but that is the general idea you're looking for I believe.

public class MyClass {
  private Int32 mySomeValue;
  public void setSomeValue(Double value) { this.mySomeValue = Convert.ToInt32(value); }
  public void setSomeValue(Int32 value) { this.mySomeValue = value; }
}
Joe Philllips