Use switch with singleton objects

  • Thread starter Thread starter cody
  • Start date Start date
C

cody

Why can't we use switches with singleton objects? I know that the compiler
cannot optimize them like constant values but the same is true for strings
and they are allowed in switches.

The reason is that I often use singleton classes as replacement for enum's
because enums does'nt provide me a (localizeable) names or descriptions when
I for example fill comboboxes with them.

Additionally I don't like that I can't put any code in the enum class
although I often have a lot of code that should be placed together with the
enum.
Maybe someaday .NET will provide an extensible and flexible enum class
feature like Java does.
 
hi,

First of all you cannot mark a type as singleton, you make it behave as a
singleton in code. That is a concept that does not exist in the language.
Therefore it will behave as a regular object to the compiler.

Now, how you expect to give unique values to the case(s) ?

FRankly I don't understand why the need of the class being a singleton.
Could you further explain why this?


cheers,
 
cody said:
Why can't we use switches with singleton objects? I know that the compiler
cannot optimize them like constant values but the same is true for strings
and they are allowed in switches.

The compiler can't even see whether they are singletons.

Is there a problem with the below?

Type t = o.GetType();
if ( t == typeof(Singleton1) ) {
// do stuff;
else if ( o == typeof(Singleton2) )
// do stuff;
else
throw new ArgumentException(
string.Format("Unknown type: {0}", t), "o"));

The reason is that I often use singleton classes as replacement for enum's
because enums does'nt provide me a (localizeable) names or descriptions when
I for example fill comboboxes with them.

Uh, couldn't you use instances? Which would give you a similar "switch":

if ( o == singleton1 ) {
// do stuff;
else if ( o == singleton2 )
// do stuff;
else
throw new ArgumentException("Unknown object", "o");
 
Currently we are using the following scheme.
The Compiler can be sure that the values passed are really unique since we
assign
static readonly values at object creation time, I think the compiler should
be able
to recognize this pattern.

public class EkpSchema : EnumWrapper
{
public static readonly EkpSchema ImmerLetzter = new EkpSchema(0, "Immer
letzter Einkaufspreis");
public static readonly EkpSchema EkpNeu = new EkpSchema(1, "EKP Neu nach
Abverkauf");
public static readonly EkpSchema ImmerDurchschnitt = new EkpSchema(2, "Immer
durchschnittl. EKP");
public static readonly EkpSchema EkpManuell = new EkpSchema(3, "EKP
manuell");

EkpSchema(int id, string bez)
:base(id,bez)
{
}

public static EkpSchema GetByID(int val)
{
return (EkpSchema)EnumWrapper.GetByID(typeof(EkpSchema), val);
}

public static EkpSchema[] GetValues()
{
return (EkpSchema[])EnumWrapper.GetValues(typeof(EkpSchema));
}

}
 
Singleton doesn't neccesarily mean that we only have *one* singleton per
class, see my other post.
 
I hear you.

I spent quite some time on exactly the same issue myself. First, I tried to
implement something similar to Color/KnowColor pair in System.Drawing. i.e.:

enum KnownSex{Male, Female};

class Sex
{
public static readonly Male = new Sex(KnownSex.Male);
public static readonly Female = new Sex(KnownSex.Female);
...
public static Sex FromKnownSex(KnownSex sex)
{
switch (sex)
{
case KnownSex.Male:
return Sex.Male;
.....
}
}

[ And please, don't laugh at the notion of "unknown sex"! I live in
Thailand, I've seen strange things ;-) ]

The idea was to have object properties (like Person.Sex) to be set to enum
values, but use objects of Sex class in comboboxes etc. But... too much work
for too little. I settled down on using singletons. It just feel "more
right" than enums. And if/else if doesn't bother me at all. All my "enum
classes" have static field called List which returns all singleton objects
of this class, not just those defined in static fields like Male and Female
instances above. I've seen from your other posting that you're doing the
same with GetValues method; good, I might not be completely crazy.
Why can't we use switches with singleton objects? I know that the compiler
cannot optimize them like constant values but the same is true for strings
and they are allowed in switches.

I guess that you can use strings in switches because they are immutable.

As for localizing the enums, earlier today I posted some code which might
give you some food for thought. I'm repeating it below.

Alexander
---------------------------------------------------------

class FriendlyNameAttribute : Attribute
{
public readonly string Value;
public FriendlyNameAttribute(string value)
{
Value = value;
}
}

enum MyEnum {
[FriendlyName("Value of One")]
One,
[FriendlyName("Value of Two")]
Two,
Three
};

class MainClass
{
public static void Main(String[] args)
{
foreach (FieldInfo fi in typeof(MyEnum).GetFields())
{
FriendlyNameAttribute[] names =
(FriendlyNameAttribute[])fi.GetCustomAttributes(typeof(FriendlyNameAttribute),
true);
if (names.Length > 0)
{
Console.WriteLine(names[0].Value);
}
else
{
Console.WriteLine(fi.Name);
}
}
}
}
 
comments inline.
I guess that you can use strings in switches because they are immutable.

My singletons also are but the compiler doesn't know that :)
As for localizing the enums, earlier today I posted some code which might
give you some food for thought. I'm repeating it below.

Alexander
---------------------------------------------------------

class FriendlyNameAttribute : Attribute
{
public readonly string Value;
public FriendlyNameAttribute(string value)
{
Value = value;
}
}

enum MyEnum {
[FriendlyName("Value of One")]
One,
[FriendlyName("Value of Two")]
Two,
Three
};

class MainClass
{
public static void Main(String[] args)
{
foreach (FieldInfo fi in typeof(MyEnum).GetFields())
{
FriendlyNameAttribute[] names =
(FriendlyNameAttribute[])fi.GetCustomAttributes(typeof(FriendlyNameAttribute
),
true);
if (names.Length > 0)
{
Console.WriteLine(names[0].Value);
}
else
{
Console.WriteLine(fi.Name);
}
}
}
}


This is a very great idea, it serves a friendyname which can be applied to
*any* type. It would also be extensible:

class FriendlyNameAttribute : Attribute
{
// ...

public static string GetFriedlyNameOf(Type t)
{
// get attribute here
}

public static string GetFriedlyNameOf(Enum e)
{
// get attribute here
}
}
 
cody said:
Singleton doesn't neccesarily mean that we only have *one* singleton per
class, see my other post.

In that case I think you're using the terminology in a way which is
different to what everyone else understands by "singleton". To me, a
singleton type is one which prevents the construction of more than one
instance of itself, and usually allows easy access to that one
instance.

What exactly do *you* mean by singleton?
 
A class to which a fixed number ob instances exist and nobody can create
additionally instances.
The class has a private ctor and no factory methods but provides an
accesssor to each instance.
 
cody said:
A class to which a fixed number ob instances exist and nobody can create
additionally instances. The class has a private ctor and no factory methods
but provides an accesssor to each instance.

Ah. That's similar to the normal meaning of singleton, but definitely
isn't the normal one. Sounds more like a flyweight to me. The "single"
part of "singleton" gives the clue that it only allows a *single*
instance.

In fact, your desired usage sounds quite like that of the enums which
are new to Java 1.5. What you could do is create a class which exposes
something like "EnumValue" as a property, and have an enum of the
actual values, which is used during construction. You could then switch
on that enum value.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top