Click here to Skip to main content
13,299,495 members (57,548 online)
Click here to Skip to main content
Add your own
alternative version


2 bookmarked
Posted 19 Aug 2011

Using Lazy for properties - Hack and slash attempt

, 19 Aug 2011
Rate this:
Please Sign up or sign in to vote.
Getting Lazy to work for me.


OK, I love the idea of the Lazy<T> class, but it never seems to do what I want it to. Assuming you don't think I'm wanting too much. If you have a simpler way, please let me know!


I'm using the lazy loading for properties of a data or business entity. Example non-lazy classes:

class User { int id; UserType userType; }  
class UserType { int id; string Name; }

This is what I would want my lazy loading to handle for the above example:

  1. new User() --> UserType should be set to null.
  2. User.PopulateBy(id) --> Gets info for User, including the ID of the UserType. UserType should lazy load from the ID if someone requests that property.
  3. User.UserTypeId = Id --> Same as #2, but emphasizing that the UserType can be changed.
  4. User.UserType = UserType --> Sets the UserType. Does not need to go to the database.
  5. Save() --> Gets the UserTypeId. It should not need to load the UserType from the database.

So Lazy<T> isn't specific enough to do what I want. I tried to implement it, but it got messy. Take a peek.


Here's what my User class looks like:

public class User {
    public int Id { get; set; }
    public string Name { get; set; }

    //assuming: passing the UserType constructor
    //an Id causes it to populate itself.
    private LazyProperty<UserType> _userType = 
      new LazyProperty<UserType>((id) => new UserType(id), (u) => u.Id);
    public int? UserTypeId {
        get { return _userType.Id; }
        set { _userType.Set(value); }
    public UserType UserType {
        get { return _userType.Value; }
        set { _userType.Set(value); }

To make the above work, below is the code that I came up with:

using System;
using System.Threading;

public class LazyProperty<T> where T : class {
    public delegate T CreateProperty<T>(int id);
    public delegate int GetId(T item);

    #region members
    int? _id = null;
    bool? _isThreadSafe;
    T _value;
    Lazy<T> _Lazy;
    GetId _GetId;
    CreateProperty<T> _createEntity;
    LazyThreadSafetyMode? _mode;

    #region Properties
    public int? Id { 
        get { return _id; }
    public T Value { 
        get {
            if (_Lazy == null)
                return _value;
                return _Lazy.Value;
    public bool IsValueCreated {
        get {
            if (_Lazy == null)
                return true;
                return _Lazy.IsValueCreated;
    private T doCreate(){
        return _createEntity(Id.Value);

    public LazyProperty(CreateProperty<T> creator, GetId getId) : 
           this(creator, getId, null, null) { }
    public LazyProperty(CreateProperty<T> creator, GetId getId, 
           bool isThreadSafe) : this(creator, getId, isThreadSafe, null) { }
    public LazyProperty(CreateProperty<T> creator, GetId getId, 
           LazyThreadSafetyMode mode) : this(creator, getId, null, mode) { }
    private LazyProperty(CreateProperty<T> creator, GetId getId, 
            bool? isThreadSafe, LazyThreadSafetyMode? mode) {
        _createEntity = creator;
        _isThreadSafe = isThreadSafe;
        _mode = mode;
        _GetId = getId;
        doSet(null, null);
    public void Set(int? id) {
        doSet(id, null);
    public void Set(T value) {
        int? id = null;
        if (value != null)
            id = _GetId(value);
        doSet(id, id == null ? null : value);
    private void doSet(int? id, T value) {
        _id = id;
        _value = value;
        if (id == null || value != null)
            _Lazy = null;
        else if (_mode.HasValue)
            _Lazy = new Lazy<T>(doCreate, _mode.Value);
        else if (_isThreadSafe.HasValue)
            _Lazy = new Lazy<T>(doCreate, _isThreadSafe.Value);
            _Lazy = new Lazy<T>(doCreate);


Again, this seems like I needed to do a lot of work to make things work for me. How would you do it better?


(Made code slightly cleaner... it's too late on a Friday for this.)


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer
United States United States
likes boardgames, computer games, and enjoys his .net programming job.

You may also be interested in...

Comments and Discussions

SuggestionNeeds some work Pin
DaveAuld19-Aug-11 23:24
mentorDaveAuld19-Aug-11 23:24 
GeneralRe: Needs some work Pin
ColinBashBash23-Aug-11 12:04
memberColinBashBash23-Aug-11 12:04 
Thanks. I'll try to fix this up soon. I was really hoping somebody would take one look at it and tell me why everything was worthless and how I could have done it some other way. I suppose I still need more explanation before I get that kind of feedback. Smile | :)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171207.1 | Last Updated 19 Aug 2011
Article Copyright 2011 by ColinBashBash
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid