I have a situation where I need to generate a few similar anonymous delegates. Here's an example:
public void Foo(AnotherType theObj)
{
var shared = (SomeType)null;
theObj.LoadThing += () =>
{
if(shared == null)
shared = LoadShared();
return shared.Thing;
};
theObj.LoadOtherThing += () =>
{
if(shared == null)
shared = LoadShared();
return shared.OtherThing;
};
// more event handlers here...
}
The trouble I'm having is that my code isn't very DRY. The contents of each of the event handlers is EXTREMELY similar, and could be easily parameterized into a factory method. The only thing preventing me from doing that is that each delegate needs to share the reference to the shared
variable. I can't pass shared
to a factory method with the ref
keyword, as you can't create a closure around a ref
varaiable. Any ideas?
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
Originally Answered: What is the full form of C ? C - Compiler . C is a general-purpose, high-level language that was originally developed by Dennis M. Ritchie to develop the UNIX operating system at Bell Labs. C was originally first implemented on the DEC PDP-11 computer in 1972.
The letter c was applied by French orthographists in the 12th century to represent the sound ts in English, and this sound developed into the simpler sibilant s.
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
There's no problem that can't be solved by adding more abstraction. (*)
The pattern you are repeating over and over again is the "lazy loading" pattern. That pattern is highly amenable to being captured in a type, and in fact, it has been, in version 4 of the framework. Documentation here:
http://msdn.microsoft.com/en-us/library/dd642331.aspx
You could then do something like:
public void Foo(AnotherType theObj)
{
var shared = new Lazy<SomeType>(()=>LoadShared());
theObj.LoadThing += () => shared.Value.Thing;
theObj.LoadOtherThing += () => shared.Value.OtherThing;
// more event handlers here...
}
And there you go. The first time shared.Value
is accessed the value gets loaded; every subsequent time the cached value is used. Extra bonus: this is even threadsafe should the shared value be accessed on multiple threads. (See the documentation for details about precisely what guarantees we make regarding thread safety.)
(*) Except of course for the problem "I have too much abstraction."
Add an extra layer of indirection. Create a class that is just a wrapper for the data that you want to keep:
public class MyPointer<T>
{
public T Value{get;set;}
}
New up a MyPointer<SomeType>
at the start of the method and pass it into the factory. Now the MyPointer
reference is copied by value, so you can't change the MyPointer
instance, but you can change the Value
in each of the factory methods and it is reflected elsewhere.
How about:
public void Foo(AnotherType theObj)
{
var shared = (SomeType)null;
Action handler = () =>
{
if(shared == null)
shared = LoadShared();
return Shared.Thing;
};
theObj.LoadThing += handler;
theObj.LoadOtherThing += handler;
// more event handlers here...
}
You can also put the Action in a method and pass a parameter:
public void Foo(AnotherType theObj)
{
var shared = (SomeType)null;
theObj.LoadThing += () => Handle("LoadThing");
theObj.LoadOtherThing += () => Handle("LoadOtherThing");
// more event handlers here...
}
private T Handle<T>(T returnParameter)
{
if(shared == null)
shared = LoadShared();
return returnParameter;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With