Factory and Generic class: are wildcards necessary?

J

Jock

Hi all,
Could anybody suggest what should be the return type of the method Create in
the Factory class?
In Java I would have used the wildcards, but here in C# apparently there is
no way do do it?!?


public class B<T>
{
}

public class D1 : B<int>
{
}

public class D2 : B<float>
{
}

public static class Factory
{
public static B<?> Create(string _name)
{
if (_name.Equals("D1"))
{
return new D1();
}
else
{
return new D2();
}
}
}

Jock
 
A

Aboulfazl Hadi

Hi
from : http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx


Not surprisingly, he'd like very much to be able to add this to C#, but
there are additional complications in C# that make that very difficult
(in Java, wildcard types were added at the same time as generics - in
C# we've got a significant compatability problem, plus in Java generics
exist only in the compiler, not in the run-time type system like in the
CLR). So, unfortunately, I wouldn't hold your breath waiting for this
in C# 3.0

A.Hadi
 
W

William Stacey [MVP]

You could do something like:

public class B<T>

{

}



public class D1<T> : B<T>

{

}



public class D2<T> : B<T>

{

}



public static class Factory

{

public static B<int> CreateInt()

{

return new D1<int>();

}

public static B<float> CreateFloat()

{

return new D2<float>();

}

}


You want to know the type at compile time. That is kinda the point of
generics.

--
William Stacey [MVP]

| Hi all,
| Could anybody suggest what should be the return type of the method Create
in
| the Factory class?
| In Java I would have used the wildcards, but here in C# apparently there
is
| no way do do it?!?
|
|
| public class B<T>
| {
| }
|
| public class D1 : B<int>
| {
| }
|
| public class D2 : B<float>
| {
| }
|
| public static class Factory
| {
| public static B<?> Create(string _name)
| {
| if (_name.Equals("D1"))
| {
| return new D1();
| }
| else
| {
| return new D2();
| }
| }
| }
|
| Jock
|
|
|
|
 
L

Lebesgue

This is a silly solution, but it works. Sometimes you'll have to add some
polymorphic methods to AnyB to make sure you can get the values from its
inheritors without explicit casts, and sometimes it is not even possible to
apply this pattern, but it's the only one I know of that works.

class AnyB
{
protected AnyB() {}
}

class B<T> : AnyB {...}

class D1 : B<int> {...}
class D2 : B<string> {...}

public class Factory
{
public static AnyB Create(string name)
{
if (name.Equals("D1"))
{
return new D1();
}
else
{
return new D2();
}
}
}
 
J

JocK

You could do something like:
public class B<T>

{

}



public class D1<T> : B<T>

{

}



public class D2<T> : B<T>

{

}



public static class Factory

{

public static B<int> CreateInt()

{

return new D1<int>();

}

public static B<float> CreateFloat()

{

return new D2<float>();

}

}


You want to know the type at compile time. That is kinda the point of
generics.


William,

this is not the aim of a factory that should be called without any
knoledge of the type of the object it is going to create. On your
solution the user of factory is supposed to know in advance which type
of object to create, indeed is up to the user to choose between
CreateFloat() or CreateInt() or CreateWhatEver().
Thanks anyway

Jock
 
J

JocK

This is a silly solution, but it works. Sometimes you'll have to add some
polymorphic methods to AnyB to make sure you can get the values from its
inheritors without explicit casts, and sometimes it is not even possible to
apply this pattern, but it's the only one I know of that works.

class AnyB
{
protected AnyB() {}
}

class B<T> : AnyB {...}

class D1 : B<int> {...}
class D2 : B<string> {...}

public class Factory
{
public static AnyB Create(string name)
{
if (name.Equals("D1"))
{
return new D1();
}
else
{
return new D2();
}
}
}

Ok it works but it forces to have a super class of B<T> which might be
inappropriate :)

Anyway I belive that without wildcards or something like that it is
impossible

Thanks
Jock
 
J

JocK

Hi
from : http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx


Not surprisingly, he'd like very much to be able to add this to C#, but
there are additional complications in C# that make that very difficult
(in Java, wildcard types were added at the same time as generics - in
C# we've got a significant compatability problem, plus in Java generics
exist only in the compiler, not in the run-time type system like in the
CLR). So, unfortunately, I wouldn't hold your breath waiting for this
in C# 3.0

A.Hadi

Thanks for the good link!

Do you know what kind of improvement Generics will have in C# 3.0?

Do you know when C# 3.0 it is going to be released?

Thanks

Jock
 
W

William Stacey [MVP]

| this is not the aim of a factory that should be called without any
| knoledge of the type of the object it is going to create.

In efffect, that is exactly what your doing anyway. Your just using a
string label instead of a clr type. You could forget about generics on the
types and use containment of your generics such as:

public abstract class B

{

public static B Create(string name)

{

if (name == "D")

return new D();

else if (name == "C")

return new C();

else

throw new ArgumentException("name invalid.");

}

}

public class D : B

{

List<int> list = new List<int>();

}

public class C : B

{

List<float> list = new List<float>();

}
 

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

Top