Portál AbcLinuxu, 30. dubna 2025 16:58
<phone:PhoneApplicationPage x:Class="SmartDial.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:helpers="clr-namespace:SmartDial.Helpers" xmlns:viewmodels="clr-namespace:SmartDial.ViewModels" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True"> <phone:PhoneApplicationPage.DataContext> <viewmodels:MainViewModel /> </phone:PhoneApplicationPage.DataContext> <!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Button Content="Sample button" /> </Grid> </phone:PhoneApplicationPage>Hlavní pes nechť je zakopán v této poloze:
using System; namespace SmartDial.Helpers { public class ContactsCache { protected readonly ContactsCache _instance = new ContactsCache(); public ContactsCache Instance { get { return _instance; } } static ContactsCache() { } public ContactsCache() { } }Tato třída je jedním z návrhů singletonu, neboli třídy, u které chceme, aby měla vždy jen jedinou instanci přístupnou přes
ContactsCache.Instance
. Ovšem pozor, u konstruktoru mi přebývá klíčové slovo public
a mám ještě jednu zradu v klíčových slovech - u _instance a Instance mi chybí static
.
Proč je tak důležité, aby konstruktor singletonu nebyl public? Podívejte se na následující průšvih a spojte si ho s předchozím kódem:
public class MainViewModel { public MainViewModel() { this.ContactsCache = new ContactsCache(); } public ContactsCache ContactsCache; }Singleton je obvykle třída navržená s záměrem, aby měla pouze jednu jedinou instanci, tedy u mě
Instance
. Současný návrh singletonu ovšem umožňuje vytvářet i další instance a společně s tímto kusem kódu způsobí, že po prvotním vytvoření instance třídy se budou neustále vytvářet další instance (taková malá rekurze), čímž dojde k přetečení zásobníku a následně k vyvolání výjimky System.StackOverflowException.
PhoneApplicationPage.DataContext
), který v konstruktoru volá výše zmíněný řádek kódu (new ContactsCache()
), Visual Studio a Expression Blend se budou pokoušet načíst strukturu ViewModelu, tedy zavolají konstruktor ViewModelu, ten zavolá zase konstruktor ContactsCache (- poslední krok se opakuje do nekonečna) - a proto po krátké době spadnou. A zase kvůli StackOverflowException. Nejsou ty nové technologie prostě skvělé?
Tiskni
Sdílej:
interface Interface<T> {} class Bang<T> implements Interface<Interface<? super Bang<Bang<T>>>> { static void bang() { Interface<? super Bang<Byte>> bang = new Bang<Byte>(); } }
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.