Reputation: 17196
The following snippets demonstrate a question that I have been encountering alot lately.
Basically I want to know if there is a better solution to hiding the backing value of a property than the use of inheritance as shown.
As a side question, is the feature implied by my non-compiling solution something that might be good for a future version of C#?
// This is a service that supplies a value but doesn't want to be called
// until needed.
static class Service
{
public static int GetP()
{
Console.WriteLine ("doing work...");
return 1;
}
}
// This is a class that implements a property which calls the service
// the first time that property is accessed but nothing stops the
// same code from accidentally referencing the uninitialized backing value.
class C
{
void F()
{
// Easy to accidentally reference backing value of property
Console.WriteLine (this.p);
}
int p = 0;
int P
{
get
{
if(p == 0)
p = Service.GetP();
return p;
}
}
}
Solution using inheritance and protected property with private backing value.
// This class hides the backing value and exposed the property the derived class.
class CBase
{
int p = 0;
protected int P
{
get
{
if(p == 0)
p = Service.GetP();
return p;
}
}
}
class C1 : CBase
{
void F()
{
// Now I can't see the backing value but I've used inheritance for the sole purpose of hiding it
Console.WriteLine (this.P);
}
}
What about if a const could be in the body of an instance level method/property that delayed setting until first runtime usage?
class D
{
int P
{
get
{
const int a = Service.GetP(); // Doesn't compile
return a;
}
}
}
Upvotes: 3
Views: 124
Reputation: 16413
If you're using .net 4, just use the Lazy class
class C
{
private Lazy<int> p = new Lazy<int>(() => Service.GetP());
private int P
{
get
{
return p.Value;
}
}
}
The first time you access Lazy.Value, the function supplied to the constructor will be called to initialize the value.
Upvotes: 3