In the following code:
public class SomeClass
{
// ... constructor and other stuff
public in SomeProperty
{
get
{
return SomeHeavyCalculation();
}
}
}
I consider the class to be immutable, so every time SomeProperty is accessed, same value should be returned. My question is whether it is possible to avoid calculating the value each time. Is there some built in mechanism for caching such stuff?
Yup - Lazy<T>, assuming you're using .NET 4:
public class SomeClass
{
private readonly Lazy<Foo> foo = new Lazy<Foo>(SomeHeayCalculation);
// ... constructor and other stuff
public Foo SomeProperty
{
get
{
return foo.Value;
}
}
}
I assume you're trying to avoid performing the calculation if the property is never accessed. Otherwise, just perform it upfront on construction.
Note that properties are often understood to be "cheap" to evaluate - and while you're making this lazy so that later accesses are cheap, this is still potentially going to be "heavy" enough on the first access to make a property inappropriate. Consider a ComputeXyz method instead.
Just cache the calculation in a private variable like so:
public class SomeClass
{
// ... constructor and other stuff
private int? calculation = null;
public int SomeProperty
{
get
{
if (!calculation.HasValue)
calculation = SomeHeayCalculation();
return calculation.Value;
}
}
}
Other than what Jon suggested, you could use this pattern:
public class SomeClass
{
// ... constructor and other stuff
private Foo _foo;
public Foo SomeProperty
{
get
{
return _foo ?? (_foo = SomeHeayCalculation());
}
}
}
It's worth noting that this really breaks down (read: becomes less readable) for value types, unless you want to wrap them in Nullable<T>. In that's your case, you may want to stick with Lazy<T> if available.
Just keep a flag to remember if the calculation have been done.
public class SomeClass
{
// ... constructor and other stuff
private bool _propertyCalculated;
private int _someProperty;
public int SomeProperty
{
get
{
if (!_propertyCaculated)
{
_someProperty = SomeHeayCalculation();
_propertyCaculated = true;
}
return _someProperty;
}
}
}
Related
Using Ninject, I have an interface that I want to bind to single instance of a concrete implementation. For example:
public interface IFoo { //... }
public class Foo { //... }
Now normally, I'd just bind something like this like so:
kernel.Bind<IFoo>().To<Foo>().InSingletonScope();
But, I need to add parameters to the constructor for Foo. Normally, again, that wouldn't be too much of a problem (I think):
kernel.Bind<IFoo>()
.To<Foo>()
.InSingletonScope()
.WithConstructorArgument("bar", myBar);
Now the problem is that I can't know the value of myBar at the time I set up all my bindings. I need to defer that until the first time I need an IFoo (and note, in reality I have several arguments to pass). So what I need is a singleton, that will be lazy initialized on first use and only gets arguments at that point.
What's the best way to approach this? I'm assuming something with Factory is probably the solution, but I don't quite see the right way to do this. I don't want to create a new Foo every time.
As in my comment above. the real problem is that you may not have the construction parameters when you need Foo. In this pattern you can Bind all your interfaces as you please and call IInitialiser.Initialise when you are ready (obvs you need to keep a reference or make it static).
Foo will throw an exception if you call it before its been properly set up
IFoo remains unchanged
IInitialiser implementations can be tweaked to poll a DB or respond to events or whatever suits your late configuration senario best
using System;
namespace UnitTestProject3
{
public interface IFoo
{
int GetAllTheFoo();
}
public interface IInitialiser
{
void Initialise(int x);
int GetX();
bool IsReady { get; }
}
public class Foo : IFoo
{
private bool isInitalised;
private int x;
private IInitialiser i;
public Foo(IInitialiser i)
{
this.isInitalised = false;
this.i = i;
}
protected void Init()
{
if (this.isInitalised)
{
return;
}
else if (i.IsReady)
{
x = i.GetX();
this.isInitalised = true;
return;
}
else
{
throw new Exception("you have not set x");
}
}
public int GetAllTheFoo()
{
Init();
return x;
}
}
}
You can use the Factory extension.
public interface IFooFactory
{
IFoo CreateFoo(string bar);
IFoo CreateFoo();
}
public interface IFoo
{
string Bar { get; set; }
}
public class Foo : IFoo
{
public string Bar { get; set; }
public Foo(string bar)
{
Bar = bar;
}
}
kernel.Bind<IFoo>().To<Foo>().InSingletonScope();
kernel.Bind<IFooFactory>().ToFactory();
IFoo foo1 = fooFactory.CreateFoo("myBar");
IFoo foo2 = fooFactory.CreateFoo("myDifferentBar"); // value is basically ignored here
IFoo foo3 = fooFactory.CreateFoo();
This will always return the same instance of Foo. Of course if you call the paremeterless method first it will result in an exception.
Given the other two answers, I could be completely missing the point of the question, but why would not something as simple as this work for you:
kernel.Bind<IFoo>().ToMethod(x => CreateFoo()).InSingletonScope();
CreateFoo will be responsible for constructing your single object with whatever set of parameters that you need. By the time CreateFoo is called you should already know what the parameters are.
In my class I have private variable, which I use inside the class only through get/set. Sometimes I forget, that I shouldn't use variable directly (even within the class) and must use get/set.
How to make that the only way to use a variable were get/set?
public class A {
int x;
public XVariable {
get { return x; }
set { x = value }
// some additional operations
}
void SomeMethod() {
x = 5; // no
XVariable = 5; // yes
}
}
C# has auto properties. No backing field needed in your code.
public class A {
public XVariable {
get;
set;
}
}
You can also have different access modifiers. Like if you want to only be able to set it from within the class.
public class A {
public XVariable {
get;
private set;
}
}
There won't be a backing field accessible from your code, but the compiler will generate one in the MSIL (what C# compiles to). You don't have to worry about that part though.
A potential downside Joe pointed out to auto props, sometimes you need to perform other actions (especially event handlers) in your property when you set something. But that's not possible with auto props. In that case, his answer would be more appropriate. But if that's not a concern for your use case, then my answer should be sufficient.
You can create a base class, and do all your real work in the derived class:
public class SomeBaseClass {
private int _x;
public int X { get { return _x; } set { _x = value; } }
}
public class DerivedClass : SomeBaseClass {
void DoSomething() {
// Does not have access to _x
}
}
Many people prefix their private variables with an underscore to help signify the variable is private. (Although it is a matter of opinion, some people like it and some don't) There is a bit more insight on this question.
You can however, scrap the field and use an auto property such as:
public XVariable { get; set; }
An auto property will store an anonymous backing field "out of view".
Is there an easy way to make an instance immutable?
Let's do an example, I have a class holding a lots of data fields (only data, no behavior):
class MyObject
{
// lots of fields painful to initialize all at once
// so we make fields mutable :
public String Title { get; set; }
public String Author { get; set; }
// ...
}
Example of creation:
MyObject CreationExample(String someParameters)
{
var obj = new MyObject
{
Title = "foo"
// lots of fields initialization
};
// even more fields initialization
obj.Author = "bar";
return obj;
}
But now that I have fully created my object, I don't want the object to be mutable anymore (because the data consumer will never need to change the state), so I would like something like that List.AsReadOnly:
var immutableObj = obj.AsReadOnly();
But if I want this behavior, I need to make another class that have exactly the same fields but without setter.
So is there any automatic way to generate this immutable class ? Or another way to allow mutability during creation but immutable once initialized ?
I know that fields can be marked as "readonly", but the object will be initialized outside of the class, and passing all fields as constructor parameters seems like a bad idea (too much parameters).
No, there is no easy way to make any type immutable, especially not if you want "deep" immutability (i.e. where no mutable object can be reached through the immutable object). You will have to explicitly design your types to be immutable. The usual mechanisms to make types immutable are these:
Declare (property-backing) fields readonly. (Or, starting with C# 6 / Visual Studio 2015, use read-only auto-implemented properties.)
Don't expose property setters, only getters.
In order to initialize (property-backing) fields, you must initialize them in the constructor. Therefore, pass the (property) values to the constructor.
Don't expose mutable objects, such as collections based on mutable-by-default types (like T[], List<T>, Dictionary<TKey,TValue>, etc.).
If you need to expose collections, either return them in a wrapper that prevents modification (e.g. .AsReadOnly()), or at the very least return a fresh copy of the internal collection.
Use the Builder pattern. The following example is too trivial to do the pattern justice, because it's usually recommended in cases where non-trivial object graphs need to be created; nevertheless, the basic idea is something like this:
class FooBuilder // mutable version used to prepare immutable objects
{
public int X { get; set; }
public List<string> Ys { get; set; }
public Foo Build()
{
return new Foo(x, ys);
}
}
class Foo // immutable version
{
public Foo(int x, List<string> ys)
{
this.x = x;
this.ys = new List<string>(ys); // create a copy, don't use the original
} // since that is beyond our control
private readonly int x;
private readonly List<string> ys;
…
}
Hmm I will enumerate my first thought on this...
1. Use internal setters if your only worry is manipulation outside of your assembly. internal will make your properties available to classes in the same assembly only. For example:
public class X
{
// ...
public int Field { get; internal set; }
// ...
}
2. I don't agree that it's necessarily a bad idea to have lots of parameters in your constructor.
3. You could generate another type at runtime that is a read-only version of your type. I can elaborate on this, but personally I think this is overkill.
Best, Iulian
As another solution you can use Dynamic Proxy. Alike approach was used for Entity Framework http://blogs.msdn.com/b/adonet/archive/2009/12/22/poco-proxies-part-1.aspx. Here is example how you can do it using Castle.DynamicProxy framework. This code is based on original example from Castle Dynamic proxy (http://kozmic.net/2008/12/16/castle-dynamicproxy-tutorial-part-i-introduction/)
namespace ConsoleApplication8
{
using System;
using Castle.DynamicProxy;
internal interface IFreezable
{
bool IsFrozen { get; }
void Freeze();
}
public class Pet : IFreezable
{
public virtual string Name { get; set; }
public virtual int Age { get; set; }
public virtual bool Deceased { get; set; }
bool _isForzen;
public bool IsFrozen => this._isForzen;
public void Freeze()
{
this._isForzen = true;
}
public override string ToString()
{
return string.Format("Name: {0}, Age: {1}, Deceased: {2}", Name, Age, Deceased);
}
}
[Serializable]
public class FreezableObjectInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
IFreezable obj = (IFreezable)invocation.InvocationTarget;
if (obj.IsFrozen && invocation.Method.Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
{
throw new NotSupportedException("Target is frozen");
}
invocation.Proceed();
}
}
public static class FreezableObjectFactory
{
private static readonly ProxyGenerator _generator = new ProxyGenerator(new PersistentProxyBuilder());
public static TFreezable CreateInstance<TFreezable>() where TFreezable : class, new()
{
var freezableInterceptor = new FreezableObjectInterceptor();
var proxy = _generator.CreateClassProxy<TFreezable>(freezableInterceptor);
return proxy;
}
}
class Program
{
static void Main(string[] args)
{
var rex = FreezableObjectFactory.CreateInstance<Pet>();
rex.Name = "Rex";
Console.WriteLine(rex.ToString());
Console.WriteLine("Add 50 years");
rex.Age += 50;
Console.WriteLine("Age: {0}", rex.Age);
rex.Deceased = true;
Console.WriteLine("Deceased: {0}", rex.Deceased);
rex.Freeze();
try
{
rex.Age++;
}
catch (Exception ex)
{
Console.WriteLine("Oups. Can't change that anymore");
}
Console.WriteLine("--- press enter to close");
Console.ReadLine();
}
}
}
I would suggest having an abstract base type ReadableMyObject along with derived types MutableMyObject and ImmutableMyObject. Have constructors for all the types accept a ReadableMyObject, and have all the property setters for ReadableMyObject call an abstract ThrowIfNotMutable method before updating their backing field. Additionally, have ReadableMyObject support a public abstract AsImmutable() method.
Although this approach will require writing some boilerplate for each property of your object, that will be the extent of the required code duplication. The constructors for MutableMyObject and ImmutableMyObject will simply pass the received object to the base-class constructor. Class MutableMyObject should implement ThrowIfNotMutable to do nothing, and AsImmutable() to return new ImmutableMyObject(this);. Class ImmutableByObject should implement ThrowIfNotMutable to throw an exception, and AsImmutable() to return this;.
Code which receives a ReadableMyObject and wants to persist its contents should call its AsImmutable() method and store the resulting ImmutableMyObject. Code which receives a ReadableMyObject and wants a slightly-modified version should call new MutableMyObject(theObject) and then modify that as required.
You kind of hinted at a way in your question, but I'm not sure if this is not an option for you:
class MyObject
{
// lots of fields painful to initialize all at once
// so we make fields mutable :
public String Title { get; protected set; }
public String Author { get; protected set; }
// ...
public MyObject(string title, string author)
{
this.Title = title;
this.Author = author;
}
}
Due to the constructor being the only way of manipulating your Author and Title, the class is in effect immutable after construction.
EDIT:
as stakx mentioned, I too am a big fan of using builders - especially because it makes unit testing easier. For the above class you could have a builder such as:
public class MyObjectBuilder
{
private string _author = "Default Author";
private string _title = "Default title";
public MyObjectBuilder WithAuthor(string author)
{
this._author = author;
return this;
}
public MyObjectBuilder WithTitle(string title)
{
this._title = title;
return this;
}
public MyObject Build()
{
return new MyObject(_title, _author);
}
}
This way you can construct your objects with default values, or override them as you please, but MyObject's properties can't be changed after construction.
// Returns a MyObject with "Default Author", "Default Title"
MyObject obj1 = new MyObjectBuilder.Build();
// Returns a MyObject with "George R. R. Martin", "Default Title"
MyObject obj2 = new MyObjectBuilder
.WithAuthor("George R. R. Martin")
.Build();
If you ever need to add new properties to your class, it's much easier to go back to your unit tests that consume from a builder rather than from a hardcoded object instantiation (i don't know what to call it, so pardon my terms).
Well, if you have too many parameters and you dont want to do constructors with parameters....here is an option
class MyObject
{
private string _title;
private string _author;
public MyObject()
{
}
public String Title
{
get
{
return _title;
}
set
{
if (String.IsNullOrWhiteSpace(_title))
{
_title = value;
}
}
}
public String Author
{
get
{
return _author;
}
set
{
if (String.IsNullOrWhiteSpace(_author))
{
_author = value;
}
}
}
// ...
}
Here's another option. Declare a base class with protected members and a derived class that redefines the members such that they are public.
public abstract class MyClass
{
public string Title { get; protected set; }
public string Author { get; protected set; }
public class Mutable : MyClass
{
public new string Title { get { return base.Title; } set { base.Title = value; } }
public new string Author { get { return base.Author; } set { base.Author = value; } }
}
}
Creating code will use the derived class.
MyClass immutableInstance = new MyClass.Mutable { Title = "Foo", "Author" = "Your Mom" };
But for all cases where immutability is expected, use the base class:
void DoSomething(MyClass immutableInstance) { ... }
Say, we have two classes:
public class A
{
protected static readonly int DefaultValue = 123;
int value;
public A()
{
value = DefaultValue;
}
public A(int _value)
{
value = _value;
}
}
public class B : A
{
public B(XElement x)
: base(x.Element("int") == null
? A.DefaultValue
: (int)x.Element("int"))
{
}
}
I understand that I could make a parameterless constructor for class B::
public B():base()
{
}
and have smth like this:
B objB = (x.Element("int") == null)?new B():new B((int)x.Element("int"));
but I'd love to have this logic encapsulated in class B.
Also I see I can do some kind of static factory method and have it encapsulated (and even make those class B constructors private if necessary):
public static B GetInstance(XElement x)
{
return (x.Element("int") == null)?new B():new B((int)x.Element("int"));
}
But I'd love to be able to have smth like the following pseudo code:
public class A
{
//don't need this anymore
//protected static readonly int DefaultValue = 123;
int value;
public A()
{
value = 123;
}
public A(int _value)
{
value = _value;
}
}
public class B : A
{
public B(XElement x)
: x.Element("int") == null
? base()
: base((int)x.Element("int"))
{
}
}
Or is there any other approach which could do the same thing as nice and even better?
The only condition that can change the base constructor used is the actual constructor that is called - find another approach to the problem :)
A factory method is one way, as noted. Also, I believe Ninject (and possibly other DI frameworks) allows choosing different constructors dynamically based upon argument values. Sadly, I do not have enough DI experience ..
Another possibility in this case is to take in int? which, while it does change the interface, would allow null to be easily coalesced to the default value.
Have you tried playing around with a null int (int?) in the Class A constructor? With a optional parameter you might be able get away with one constructor.
Situation:
I often run into this problematic and never know how to solve it. Though I don't know where and how to look for answer.
So here it is. When you store some objects into other objects you can have them as readonly, or just with a getter, which is the same. This way you cannot change the value of a MyInt in
public class ClassA {
public readonly int MyInt;
public string MyString;
}
and no problem if I want to put this in a container as follows:
public class ClassB {
public readonly ClassA MyClassA;
public string MyString;
}
This will still work as expected. MyInt is readonly and MyStringA is not.
Problem:
But I can still get MyClassA and set MyClassA.MyStringA.
Is there a way to have a "stricter" readonly system?
With the above example I would like MyClassA's fields to be all readonly if MyClassA is.
The only solution I can think of is to have another class MyClassAreadonly. But that seems ugly and not not convenient.
Context:
The reason why I am looking for this behavior is that I want MyClassB.MyString to add logic (like firing an event) before setting MyClassB.MyClassA.MyString. So another solution is to simply not show ClassB.MyClassA by setting it as private. But that is nice to being able to retrieve MyClassA! But if I retrieve it and modify it I miss the ClassB logic!
PS: Despite I can't figure it out, I hope to have been clear enough.
You can wrap properties of ClassA into properties of ClassB like this:
public class ClassB
{
private readonly ClassA _myClassA = new ClassA();
private string _myString;
public string MyString
{
get
{
// your logic here
return _myString;
}
set
{
// your logic here
_myString = value;
}
}
public string MyStringA { get { return _myClassA.MyString;}}
public int MyIntA { get { return _myClassA.MyInt; }}
}
How about adding an event to ClassA that ClassB can then handle in order to implement the additional logic?
public class ClassA
{
public readonly int MyInt;
private string _myString;
public string MyString
{
get
{
return _myString;
}
set
{
_myString = value;
if (MyStringChanged != null)
{
MyStringChanged(this, new EventArgs());
}
}
}
public event EventHandler MyStringChanged;
}
public class ClassB
{
public readonly ClassA MyClassA;
//It sounds like you wanted to use ClassB.MyString to manipulate ClassA.MyString, so you probably won't need this anymore?
//public string MyString;
public ClassB()
{
MyClassA = new ClassA();
MyClassA.MyStringChanged += new EventHandler(MyClassA_MyStringChanged);
}
private void MyClassA_MyStringChanged(object sender, EventArgs e)
{
//Add your logic here
}
}
"Deep" immutability
As stated in a comment by #Damien_The_Unbeliever, here is a perfect "answer" to my question. I put answer between quote marks because there is no built-in solution for the moment in C#.
The closest alternative to address my issue will be to have an Immutable facade for the objects (MyClassA) I want to use this way.
Thanks Damien.
Another read on the subject: http://www.bluebytesoftware.com/blog/2007/11/11/ImmutableTypesForC.aspx