I would like to know the simplest code for polling a property's value, to execute the code in its getter.
Currently I'm using: instance.property.ToString();
, but I'd rather have something without possible side-effects or unnecessary overhead.

- 6,926
- 5
- 62
- 86
-
2Instance.Property will certainly execute the getter's code. Please elaborate on your question, i don't think i understand it. – mcabral Jul 07 '11 at 14:05
-
2What do you mean "possible side effects?" If you are calling a getter, the get code is executed which may (depending on how it is written) result in side effects no matter how you call it. – jlew Jul 07 '11 at 14:06
-
1@Protector - What are you trying to achieve? maybe the code you want to execute should not get in the properties getter. – tkerwood Jul 07 '11 at 14:08
-
@mcabral `Instance.Property` would indeed poll it, but that's not a complete statement. I can't just slap a semi-colon at the end of that and hope the compiler won't notice. – Protector one Jul 07 '11 at 14:08
-
@tkerwood the code in the setter retrieves a value from a database and stores in into a global variable for re-use. – Protector one Jul 07 '11 at 14:10
-
@jlew "possible side effects" like NullReferenceException if the getter returns null? – Filburt Jul 07 '11 at 14:13
-
@jlew I was thinking of side-effects in the implementation of its `ToString`. – Protector one Jul 07 '11 at 14:16
-
A setter making a DB call is, again, a bad idea – Ed S. Jul 07 '11 at 19:27
-
@Ed S. The question is dealing with a getter, not a setter, but if you have a good resource on why doing it with either is bad, I'm interested. – Protector one Jul 13 '11 at 07:44
-
@Protector one: You said in a comment above that your setter is making a DB call. Properties are intended to be simple and relatively fast. Sure, you *can* make a DB call in a setter if you like, but you should be using a method for calls that are expensive by convention. – Ed S. Jul 13 '11 at 15:33
-
@Ed S: Perhaps he is touching the property in order to coax it to make the database call and cache the property value, to be retrieved later. I'm genuinely curious about why you would ever want to do this, but nobody is offering a reasonable explanation. – Robert Harvey Jul 14 '11 at 04:09
-
@Robert This is indeed what I'm doing. Why is that so bad? – Protector one Jul 14 '11 at 08:54
-
@Protector: It's just obtuse, that's all. If you want an object that populates the properties before they are called, you can make your database call(s) in the constructor of the object, or use a separate method in the object, appropriately named: `ReadDatabaseValuesToCache()`, or something like that. Then, it's far easier for the programmer coming after you to figure out what you did...Much clearer than `instance.SomeProperty.NoOp();` – Robert Harvey Jul 14 '11 at 14:33
-
1Alternatively, you could call your extension method `Touch`, as in `instance.SomeProperty.Touch();` Then at least your code gives some clue about what's happening. – Robert Harvey Jul 14 '11 at 14:39
8 Answers
(I'm assuming you're trying to avoid the warning you get from simply assigning the value to an unused variable.)
You could write a no-op extension method:
public static void NoOp<T>(this T value)
{
// Do nothing.
}
Then call:
instance.SomeProperty.NoOp();
That won't box the value or touch it at all - just call the getter. Another advantage of this over ToString
is that this won't go bang if the value is a null reference.
It will require JIT compilation of the method once per value type, but that's a pretty small cost...

- 1,421,763
- 867
- 9,128
- 9,194
-
Wouldn't assigning it to an unused variable also waste memory? (And I indeed don't want that warning.) – Protector one Jul 07 '11 at 14:24
-
@Protector one: Possibly, but only stack memory if it's a local variable (in most situations; implementation-specific). – Jon Skeet Jul 07 '11 at 14:25
That sounds to me like a really terrible idea. Honestly, if you have logic in a getter that needs to be executed regularly, take it out of the getter and stick it in a method. I would hate to jump in and maintain code like that, and once I finally figured out why it was doing what it does I would refactor it.

- 122,712
- 22
- 185
- 265
-
Actually, most of the code only needs to be executed once—it's a singleton-pattern-like scenario. – Protector one Jul 07 '11 at 14:22
-
@Protector: That's a good argument for putting the singly-executed code in the constructor. – Robert Harvey Jul 14 '11 at 14:45
-
It will be executed once at most, but it needn't always be executed that one time. That's why I don't want it in the constructor. – Protector one Jul 14 '11 at 14:58
I would extract the code in the getter to a function and call the function both, from the getter and from your poller, if this is an option for you.

- 2,060
- 3
- 20
- 27
-
1This is probably a better solution than the one in Jon Skeet's answer, but his answers the question better. – Protector one Jul 13 '11 at 08:03
Capturing it in a variable is the best way - doesn't cause any side-effects unless the getter itself causes side-effects.
var value = someObj.Property;

- 154
- 5
-
That's true, but at least it's not a global function that has no use otherewise. ;) – WolfgangSenff Jul 07 '11 at 14:07
-
It's indeed simple code, but feels like a waste of memory to me. – Protector one Jul 07 '11 at 14:11
-
It's just a reference. It could be some primitive type, but not going to be a lot of memory either way. At the same time, what type of programming are you doing that capturing something in a variable is going to cause a problem with performance? – WolfgangSenff Jul 07 '11 at 14:24
-
It wouldn't be a problem (and simply using `ToString` wouldn't either), I'm just curious if there isn't a cleaner, simpler way to do it. – Protector one Jul 07 '11 at 14:44
I hope i understand that correct. First of all
class MyClass
{
public int Number{get;set;}
}
var cl = new MyClass();
cl.Number.ToString();
The ToString() does not necessarily return the value, for primitives this is the case, yes, but for other more complex classes it is usually only the full qualified name. And i guess this is not what you want.
To execute the getter, you need some reflection.
var propInfo = this.GetType().GetProperty("Number");
int val = (int)propInfo.GetValue(cl, null);

- 10,971
- 3
- 28
- 45
I like Jon Skeet's answer, but along the same vein, this would also work without having to write an extension method:
GC.KeepAlive(instance.SomeProperty);
The KeepAlive
method accepts an object
and does nothing with it, like the NoOp
extension method.

- 22,904
- 4
- 58
- 91
-
2No, there's an important difference - that will box any value type values. I'm also not sure what `GC.KeepAlive(null)` does. – Jon Skeet Jul 07 '11 at 14:26
I think that you need to move the code to some where else. So try setting the global var in the constructor of your 'instance' object.
OR.. (not sure what you mean by global variable) but if it is in a object, then you could just get the getter of the property on you global object to do a lazy load and get the value then.
string _myProp;
public string MyProp
{
get
{
if (String.IsNullOrWhiteSpace(_myProp))
{
_myProp = GetTheValueFromWhereEver();
}
return _myProp;
}
}
(but you probably dont have access to the 'instance' there)

- 1,875
- 16
- 26
-
This code is actually quite similar to my code! So how would you poll your `MyProp` property to make sure `_myProp` is set? (Which is what I'm asking.) – Protector one Jul 07 '11 at 14:39
-
@protector - no i am suggesting putting that code at the global level or to set up the global var from the constructor of your instance. I think to have a getter that does something other than just return a value is bad practice. sorry. – tkerwood Jul 07 '11 at 14:43
-
But I don't want the property-getter code to be executed with _every_ instance of the object. And you don't have to be sorry—you're probably right! But I'm still interested in knowing how to do it my way. – Protector one Jul 07 '11 at 14:54
-
Even though it's probably still a bad idea, I just want to leave this concise lambda solution:
((Func< [TYPE_OF_PROPERTY] >)(() => instance.Property))();

- 6,926
- 5
- 62
- 86