You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
_Lazy loading_ is a technique used to delay the execution of code for later on. There are a couple of reasons as to why you'd want to do that, and we'll enumerate some:
@@ -24,7 +23,7 @@ While the theory sounds great, there still remains the question of how do you ac
24
23
### Singletons
25
24
First, when it comes the the [_singleton pattern_](https://en.wikipedia.org/wiki/Singleton_pattern), objects (if we're talking in an _OOP_ context, but this goes for other paradigms as well) are often _statically_ allocated. This affects us even more, as static code, often get initialized early on. For example in `.NET Framework`_static_ fields get initialized before the constructor of the class is called. This is also the case for other platforms, like `Java`. Here an `if` check is usually employed for _lazy loading_:
26
25
27
-
```C#
26
+
```csharp
28
27
classSingleton
29
28
{
30
29
privatestaticSingleton_instance=null; // redundant, for explicity
@@ -52,15 +51,15 @@ Notice, the more moder `.NET` platform actually uses lazy loading by default. St
52
51
The more interesting and common use case is when we'd like to delay the initialization of an _instance_ field. For this, both frameworks (`.NET` and `.NET Framework`) come with build-in support, namely: `Lazy<T>`, a generic class which can wrap objects of any type and delay their initialization. We'll explore a simple implementation of such an idea, and see how we can achieve this in pretty much any programming language.
53
52
54
53
Frist imagine the scenario of two classes:
55
-
```C#
54
+
```csharp
56
55
publicclassFoo { ... }
57
56
```
58
57
and
59
-
```C#
58
+
```csharp
60
59
publicclassBar { ... }
61
60
```
62
61
with a _composition_ relationship of type:
63
-
```C#
62
+
```csharp
64
63
publicclassFoo
65
64
{
66
65
Barbar=new();
@@ -71,15 +70,15 @@ Our goal is to delay the initialization of the field `bar` in any `Foo` instance
71
70
72
71
From the get go, our solution needs to address any possible type, not just `Bar`. This is why _generics_ are needed. So our solution begins to look as such:
73
72
74
-
```C#
73
+
```csharp
75
74
publicclassLazy<T> { … }
76
75
```
77
76
78
77
Second, we'd need to know all about how _exactly_ to create this `bar` object, and yet, _delay_ the process… This sounds like a _producer_ – a method that produces such and object, encorporates the _how_ – and a _callback_ (_lambda_ or _higher-order function_), a method passed as argument, to be called when needed. This is exactly what we need! In `.NET` the `Func<T>` type holds a _method_ (or _function_ for you functional programmers) that takes no parameters and returns a `T` – `Func` comes in a buch of variations that also take arguments, the last one always representing the return value, such as `Func<T,TResult>`, `Func<T,T,TResult>` and so on.
79
78
80
79
We can use is as such:
81
80
82
-
```C#
81
+
```csharp
83
82
publicclassLazy<T>
84
83
{
85
84
privateFunc<T> _generator;
@@ -92,7 +91,7 @@ We can use is as such:
92
91
All that we're providing to the constructor of the `Lazy` class is a function, that describes how to return a `T`, and whenever we want to actually return that `T`, we just call `Load`.
93
92
94
93
Let's see this in action:
95
-
```C#
94
+
```csharp
96
95
publicclassFoo
97
96
{
98
97
// old code: Bar bar = new();
@@ -103,15 +102,15 @@ public class Foo
103
102
104
103
This looks great! Now, whenever we want our instance, we can just call `Load` on `bar_lazy`, but the beauty of warping things in a function is that, even if our `Bar` constructor required parameters, this would be fixed with just a small adjustment:
105
104
106
-
```C#
105
+
```csharp
107
106
publicclassFoo
108
107
{
109
108
//ctor injection, provide `lazy_bar` as a dependency
0 commit comments