Skip to content

Commit 947b4d7

Browse files
authored
Merge pull request #195 from stoiandan/master
Added picture
2 parents 6143ee9 + f689ecd commit 947b4d7

File tree

2 files changed

+11
-12
lines changed

2 files changed

+11
-12
lines changed

_posts/2024-09-16-lazy-loading-in-csharp.md

+11-12
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ layout: post
33
title: Lazy Loading in C# (and not only)
44
subtitle:
55
category: dev
6-
tags: [development, dotnet, C#]
6+
tags: [dotnet, development]
77
author: Stoian Dan
88
author_email: [email protected]
9-
header-img: "https://upload.wikimedia.org/wikipedia/commons/a/a9/British_club_scene.jpg"
9+
header-img: "images/lazy-loading-in-csharp/British_club_scene.jpg"
1010
---
11-
# Lazy Loading in C# (and not only)
1211

1312
## Introduction
1413
_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
2423
### Singletons
2524
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_:
2625

27-
```C#
26+
```csharp
2827
class Singleton
2928
{
3029
private static Singleton _instance = null; // redundant, for explicity
@@ -52,15 +51,15 @@ Notice, the more moder `.NET` platform actually uses lazy loading by default. St
5251
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.
5352

5453
Frist imagine the scenario of two classes:
55-
```C#
54+
```csharp
5655
public class Foo { ... }
5756
```
5857
and
59-
```C#
58+
```csharp
6059
public class Bar { ... }
6160
```
6261
with a _composition_ relationship of type:
63-
```C#
62+
```csharp
6463
public class Foo
6564
{
6665
Bar bar = new();
@@ -71,15 +70,15 @@ Our goal is to delay the initialization of the field `bar` in any `Foo` instance
7170

7271
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:
7372

74-
```C#
73+
```csharp
7574
public class Lazy<T> { … }
7675
```
7776

7877
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.
7978

8079
We can use is as such:
8180

82-
```C#
81+
```csharp
8382
public class Lazy<T>
8483
{
8584
private Func<T> _generator;
@@ -92,7 +91,7 @@ We can use is as such:
9291
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`.
9392

9493
Let's see this in action:
95-
```C#
94+
```csharp
9695
public class Foo
9796
{
9897
// old code: Bar bar = new();
@@ -103,15 +102,15 @@ public class Foo
103102

104103
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:
105104

106-
```C#
105+
```csharp
107106
public class Foo
108107
{
109108
//ctor injection, provide `lazy_bar` as a dependency
110109
Foo(Lazy<Bar> lazy_bar)
111110
...
112111
}
113112
```
114-
```C#
113+
```csharp
115114
// calling code
116115
lazy_bar = new Lazy<Bar> (() => new Bar(name, age, other_param))
117116
new Foo(lazy_bar);
Loading

0 commit comments

Comments
 (0)