[C#] Public constructor vermijden.

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
Hi,

ik heb de volgende code:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
namespace SnakeGame
{
    /// <summary>
    /// Singleton class
    /// </summary>
    /// <typeparam name="T">Class to be 'singletonned'</typeparam>
    class Singleton<T>
        where T: class, new()
    {
        /// <summary>
        /// Container for the instance
        /// </summary>
        private static T instance = null;

        /// <summary>
        /// empty constructor, in order to avoid auto-generated public constructor
        /// </summary>
        private Singleton()
        {
        }

        /// <summary>
        /// Get the instance of the class
        /// </summary>
        /// <returns>The one and only instance</returns>
        public static T GetInstance()
        {
            if (Singleton<T>.instance == null)
                Singleton<T>.instance = new T();

            return Singleton<T>.instance;
        }
    }
}


Hiermee kan ik heel gemakkelijk een Singleton pattern implementeren in een andere klasse.

Doch is er 1 probleem: de huidige constructie zegt: de subklasse MOET een public parameterless constructor hebben.

Dit zou ik willen vermijden,maar ik heb totaal geen idee in welke richting te zoeken.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

Verwijderd

protected constructor ervan maken?

bij mij compiled hij in ieder geval met een protected constructor.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
Verwijderd schreef op zondag 24 augustus 2008 @ 02:54:
protected constructor ervan maken?

bij mij compiled hij in ieder geval met een protected constructor.
Als ik een klasse maak:

C#:
1
2
3
4
5
6
7
8
9
10
namespace SnakeGame
{
    public class Logger : Singleton<Logger>
    {
        //protected zodat niemand die kan oproepen van buitenaf
        protected Logger() : base()
        {
        }
    }
}


Dit compileert helaas niet.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:07
Zowiezo vind ik het geen goed idee om over te erven van singletons, tenzij je singleton-base class misschien abstract is.
Maak de constructor van je base class protected, en die van je child class zal dus zowiezo private moeten zijn.

En, waarom compileert dit niet ? Welke fout krijg je nu ?
Volgens mij compileert het niet, omdat je in je generic constraint clausule zegt dat je type T een constructor moet hebben, en die zal dan moeten accessible zijn. Nu is hij private, dus is het logisch dat je 'm niet vanuit je inherited class kunt benaderen.

Dominique zei dat hij protected moest zijn, en daarmee doelde hij natuurlijk op de constructor van je base class, en niet op de constructor van je inherited class ...

Ik vraag me af waarom je die constructor van de inherited class protected zou maken ?
Je kent toch wel de betekenis van de verschillende access modifiers ?

[ Voor 13% gewijzigd door whoami op 24-08-2008 10:00 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Naar mijn idee is erven van een singleton klasse ook niet de juiste manier. Met jou implementatie is je singleton trouwens niet thread safe.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
whoami schreef op zondag 24 augustus 2008 @ 09:58:
Zowiezo vind ik het geen goed idee om over te erven van singletons, tenzij je singleton-base class misschien abstract is.
Maak de constructor van je base class protected, en die van je child class zal dus zowiezo private moeten zijn.
Heb 'm even abstract gemarked.
En, waarom compileert dit niet ? Welke fout krijg je nu ?
Volgens mij compileert het niet, omdat je in je generic constraint clausule zegt dat je type T een constructor moet hebben, en die zal dan moeten accessible zijn. Nu is hij private, dus is het logisch dat je 'm niet vanuit je inherited class kunt benaderen.

Dominique zei dat hij protected moest zijn, en daarmee doelde hij natuurlijk op de constructor van je base class, en niet op de constructor van je inherited class ...
Die heb ik ook net even aangepast,
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
namespace SnakeGame
{
    /// <summary>
    /// Singleton class
    /// </summary>
    /// <typeparam name="T">Class to be 'singletonned'</typeparam>
    abstract class Singleton<T>
        where T: class, new()
    {
        /// <summary>
        /// Container for the instance
        /// </summary>
        private static T instance = null;

        /// <summary>
        /// empty constructor, in order to avoid auto-generated public constructor
        /// </summary>
        protected Singleton()
        {
        }

        /// <summary>
        /// Get the instance of the class
        /// </summary>
        /// <returns>The one and only instance</returns>
        public static T GetInstance()
        {
            if (Singleton<T>.instance == null)
                Singleton<T>.instance = new T();

            return Singleton<T>.instance;
        }
    }
}


De constraint new() op regel 8 verplicht mij eigelijk een public constructor the hebben in mijn inherited class. Laat ik die weg, dan kan ik niet 'new T()' doen op regel 29. De compiler laat dit gewoonweg niet toe.

Fouten die ik krijg:
1) als de constructor van de inherited class niet public is krijg ik deze:
Error 1 'SnakeGame.Snake' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'SnakeGame.Singleton<T>' E:\Personal\Documents\My Dropbox\Projects\SnakeGame\SnakeGame\Snake.cs 14 8 SnakeGame
Waarbij SnakeGame.Snake mijn inherited class is.

2) als ik die new() constraint weglaat:
Error 1 Cannot create an instance of the variable type 'T' because it does not have the new() constraint E:\Personal\Documents\My Dropbox\Projects\SnakeGame\SnakeGame\Singleton.cs 29 29 SnakeGame
Ik vraag me af waarom je die constructor van de inherited class protected zou maken ?
Je kent toch wel de betekenis van de verschillende access modifiers ?
Ik wil 'm private, zodat je alleen een instance kan oproepen met GetInstance() , en niet door gewoon Snake snake = new Snake(); te doen.
Verwijderd schreef op zondag 24 augustus 2008 @ 10:58:
Naar mijn idee is erven van een singleton klasse ook niet de juiste manier. Met jou implementatie is je singleton trouwens niet thread safe.
Dan moet ik waarschijnlijk ergens locking toepassen op mijn instance, maar daar moet ik nog wat over lezen.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:07
Snake schreef op zondag 24 augustus 2008 @ 12:36:
De constraint new() op regel 8 verplicht mij eigelijk een public constructor the hebben in mijn inherited class. Laat ik die weg, dan kan ik niet 'new T()' doen op regel 29. De compiler laat dit gewoonweg niet toe.
Idd, da's wat ik zeg. Die new constraint heb je nodig, maar je zorgt er ook voor dat die public constructor verplicht is ....
Maar, waarom zou je een base class willen hebben die gewoon het singleton pattern voor je implementeert ?
Dat druist toch tegen het singleton principe in ?
Een singleton zegt: je kan slechts één instantie van een bepaalde class hebben.
Je base class is een singleton. Je erft van die base class 2 andere classes over. Aangezien overerving een is - a relationship is, wil dit dan plots zeggen dat je 2 instanties hebt van je singleton-base ...
Dan moet ik waarschijnlijk ergens locking toepassen op mijn instance, maar daar moet ik nog wat over lezen.
Je zou het kunnen doen via double-checked locking, maar dat is eigenlijk niet nodig.

Dit zou voldoende zijn om 'm thread safe te maken:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MySingleton
{
    public static MySingleton Instance
    {
          return Nested.MySingleton;
    }

    private MySingleton(){}

    private static class Nested
    {
         static Nested(){}

         internal static readonly MySingleton MySingleton = new MySingleton();
    }
}
De MySingleton member van de Nested class wordt pas gemaakt, als de static member (MySingleton) van de Nested class voor de eerste keer aangesproken wordt.
De static constructor wordt slechts aangesproken als de static member de eerste keer wordt aangesproken, en een static constructor wordt ook slechts 1x per AppDomain uitgevoerd.

edit:
nog even de private constructor toegevoegd

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
Dan zat ik dus duidelijk in de verkeerde richting :)

Ik ga dan jouw implementatie gebruiken, heel fel bedankt :)

Ik moet nog HEEL veel leren over dit.

Edit: is het misschien mogelijk om de code te zien die de compiler ervan maakt? Dus niet de bytecode, maar na optimalisatie?

[ Voor 29% gewijzigd door Snake op 24-08-2008 13:28 ]

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

Verwijderd

Snake schreef op zondag 24 augustus 2008 @ 13:17:
Edit: is het misschien mogelijk om de code te zien die de compiler ervan maakt? Dus niet de bytecode, maar na optimalisatie?
Even Reflector gebruiken van onze grote vriend Lutz Roeder.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:07
Optimalisatie gebeurt @runtime door de JIT.

Reflector gaat vziw gewoon de IL gaan vertalen naar C# of VB.NET code.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Dit is wat Microsoft zegt over thread-safe singleton op msdn

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}


Directe link: http://msdn.microsoft.com/en-us/library/ms998558.aspx

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:07
Dat is een double checked locking singleton, dat idd thread safe is, maar , in .NET kan je die locking vermijden door te werken met het voorbeeld dat ik eerder gepost heb.

Double checked locking is ook iets minder performant, en, je mag dat volatile keyword niet vergeten...

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
Zo ver zit ik nog niet, ik ga wel even inlezen over dat volatile keyword en dergelijke :)

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • jos707
  • Registratie: December 2000
  • Laatst online: 11-09 09:20
Snake schreef op zondag 24 augustus 2008 @ 22:51:
Zo ver zit ik nog niet, ik ga wel even inlezen over dat volatile keyword en dergelijke :)
Mag ik vragen welk boek je dan aan het lezen bent, lijkt mij een interessant topic dit :)

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:07
Ik vermoed dat hij dat op MSDN gaat lezen ....

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
jos707 schreef op maandag 25 augustus 2008 @ 20:41:
[...]

Mag ik vragen welk boek je dan aan het lezen bent, lijkt mij een interessant topic dit :)
Internet :)

Boeken zijn te duur. :+

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:07
Dat is kwatsch.

Er zijn boeken beschikbaar die wel wat geld kosten, maar die -imho- een verrijking zijn voor iedere software-developer.
Als je, als software developer, serieus met je vak wilt bezig zijn, dan moet je steeds opnieuw in jezelf investeren. En dan bedoel ik: bijleren, je skills uitbreiden, etc.... En daar kunnen (bepaalde) boeken je serieus mee helpen (en dan heb ik het niet over boeken als 'C# voor dummies', of andere boeken die teveel focussen op een taal of technologie).
Zelf heb ik hier een 5-tal boeken staan die ik als mijn 'bijbels' beschouw. Dat zijn boeken waar ik af en toe nog wel eens naar teruggrijp, en waar ik heel veel informatie uit gehaald heb. (Die boeken zijn -in no particular order- Domain Driven Design, het GoF boek, PoEAA, Design Patterns Explained, Refactoring).
Met lezen alleen ga je uiteindelijk je skills niet verbeteren; je moet natuurlijk ook blijven developpen, etc.. Maar boeken kunnen alleszins helpen. Net zoals het lezen van bepaalde blogs, het lezen van andermans code, etc...

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
Tuurlijk, hence the :+
Er zijn boeken beschikbaar die wel wat geld kosten, maar die -imho- een verrijking zijn voor iedere software-developer.
Als je, als software developer, serieus met je vak wilt bezig zijn, dan moet je steeds opnieuw in jezelf investeren. En dan bedoel ik: bijleren, je skills uitbreiden, etc.... En daar kunnen (bepaalde) boeken je serieus mee helpen (en dan heb ik het niet over boeken als 'C# voor dummies', of andere boeken die teveel focussen op een taal of technologie).
Zelf heb ik hier een 5-tal boeken staan die ik als mijn 'bijbels' beschouw. Dat zijn boeken waar ik af en toe nog wel eens naar teruggrijp, en waar ik heel veel informatie uit gehaald heb. (Die boeken zijn -in no particular order- Domain Driven Design, het GoF boek, PoEAA, Design Patterns Explained, Refactoring).
Met lezen alleen ga je uiteindelijk je skills niet verbeteren; je moet natuurlijk ook blijven developpen, etc.. Maar boeken kunnen alleszins helpen. Net zoals het lezen van bepaalde blogs, het lezen van andermans code, etc...
Ik ga die boeken zeker eens noteren, en op zoek :) Dankjewel ervoor :)

Wat ik kan heb ik geleerd van internet.

Heb je een boek wat uitlegt over Threading in het algemeen? Misschien Threading in C#?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 12-09 06:48

Sebazzz

3dp

Zolang je nog geen boek hebt over Threading raad ik je de volgende serie artikelen aan op CodeProject:
Beginners Guide To Threading In .NET Part 1 of n

Komt van alles in voor, van de basics, tot locking, AppDomains en ThreadPools.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • jos707
  • Registratie: December 2000
  • Laatst online: 11-09 09:20
whoami schreef op maandag 25 augustus 2008 @ 20:51:
[...]

Dat is kwatsch.

Er zijn boeken beschikbaar die wel wat geld kosten, maar die -imho- een verrijking zijn voor iedere software-developer.
...
Ben ik het volledig mee eens, tenzij je nog de basis onder de knie moet krijgen. Dan is er op het internet wel veel bruikbare 'how to' artikelen te vinden. Maar meestal blijft het ook alleen bij artikeles waardoor er niet diep genoeg wordt ingegaan op het onderwerp. Natuurlijk zijn er ook een boel slechte boeken die niks of weinig bijbrengen. Ik ben nu de MCPD training kit van Microsoft aan het lezen en vind er eigenlijk helemaal niets aan.

Maar als je toch iets goed wilt lezen over threading op het internet kan je beter hier kijken.
Pagina: 1