471,306 Members | 1,315 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,306 software developers and data experts.

Generic method to return object reference

acb
Hi,

I have a list of different objects in a <List> Structure. There is only
one category of each kind of object.

Current I have the following methods:

public static Flag GetFlagObj()
{
foreach (Thingy s in _Thingies)
{
if (s is Flag)
return (Flag)s;
}
return null;
}

public static Cloth GetFlagObj()
{
foreach (Thingy s in _Thingies)
{
if (s is Cloth)
return (Cloth)s;
}
return null;
}

public static BedSprd GetFlagObj()
{
foreach (Thingy s in _Thingies)
{
if (s is BedSprd)
return (BedSprd)s;
}
return null;
}
Is there a way I could have one generic method that would take as a
parameter the item I wish returned?

Thank you for your help.
Al

Jan 25 '06 #1
12 2173
"acb" <ch******@gmail.com> a écrit dans le message de news:
11**********************@g47g2000cwa.googlegroups. com...

| I have a list of different objects in a <List> Structure. There is only
| one category of each kind of object.
|
| Current I have the following methods:
|
| public static Flag GetFlagObj()
| {
| foreach (Thingy s in _Thingies)
| {
| if (s is Flag)
| return (Flag)s;
| }
| return null;
| }
|
| public static Cloth GetFlagObj()
| {
| foreach (Thingy s in _Thingies)
| {
| if (s is Cloth)
| return (Cloth)s;
| }
| return null;
| }
|
| public static BedSprd GetFlagObj()
| {
| foreach (Thingy s in _Thingies)
| {
| if (s is BedSprd)
| return (BedSprd)s;
| }
| return null;
| }
|
|
| Is there a way I could have one generic method that would take as a
| parameter the item I wish returned?

Yes, you do it like this :

public static T GetObj<T>()
{
foreach (Thingy s in _Thingies)
{
if (s is T)
return (T) s;
}
return default(T);
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer

Jan 25 '06 #2
possible solution: create generic search method with argument of
required type, disadvantage of this method - generic return value

static List<object> _list = new List<object>();

public static object Find(Type t)
{
return _list.Find(delegate(object obj)
{
return t.IsAssignableFrom(obj.GetType());
});
}

Jan 25 '06 #3
As an extension to this; if you are going to have a large number of items
(each of a different type, as suggested by GetObj<T> [GetThingy<T>()
perhaps?]) you could improve performance by using a Dictionary<Type,
Thingy>; when adding you use obj.GetType() as the key, and when searching
you use typeof(T) - this then gives you hashtable performance.

Also - if thingies can be added / removed outside of the static ctor, I
would strongly advise making this (static) data thread-safe - e.g.

private static Dictionary<Type, Thingy> _Thingies; // init in static ctor

public static T GetThingy<T>()
{
lock(_Thingies) {
return (T) _Thingies[typeof(T)];
}
}

public static void Add(Thingy thingy) {
if(thingy==null) throw new ArgumentNullException("thingy"); // need a
non-null thingy to call GetType()
lock(_Thingies) {
_Thingies.Add(thingy.GetType(), thingy);
}
}

// or - particularly if you accept null values for thingy
public static void Add<T>(T thingy) where T : Thingy {
lock(_Thingies) {
_Thingies.Add(typeof(T), thingy);
}
}

(or something like that; code not tested)

Marc
Jan 25 '06 #4
static List<object> _list = new List<object>();

public static T Find<T>()
{
return (T)_list.Find(delegate(object obj)
{
return (obj is T);
});
}

Jan 25 '06 #5
not important, but I omitted a useful where clause:

public static T GetThingy<T>() where T : Thingy { //...
}

Marc
Jan 25 '06 #6
"Marc Gravell" <mg******@rm.com> a écrit dans le message de news:
em**************@TK2MSFTNGP14.phx.gbl...

| As an extension to this; if you are going to have a large number of items
| (each of a different type, as suggested by GetObj<T> [GetThingy<T>()
| perhaps?]) you could improve performance by using a Dictionary<Type,
| Thingy>; when adding you use obj.GetType() as the key, and when searching
| you use typeof(T) - this then gives you hashtable performance.

Excellent addenda :-))

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jan 25 '06 #7
Some people get a new toy and they just have to use it everywhere!

For the example that you give generics are totally unnecessary and overloads
with "out" parameters will do the job and save you having to type in the
type name in the call.

public static void Get(out X x)
{
foreach(Thingy t in _Thingies)
{
x = t as X;
if( x != null )
return;
}
x = null;
}

X x;
list.Get(out x);

"acb" <ch******@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Hi,

I have a list of different objects in a <List> Structure. There is only
one category of each kind of object.

Current I have the following methods:

public static Flag GetFlagObj()
{
foreach (Thingy s in _Thingies)
{
if (s is Flag)
return (Flag)s;
}
return null;
}

public static Cloth GetFlagObj()
{
foreach (Thingy s in _Thingies)
{
if (s is Cloth)
return (Cloth)s;
}
return null;
}

public static BedSprd GetFlagObj()
{
foreach (Thingy s in _Thingies)
{
if (s is BedSprd)
return (BedSprd)s;
}
return null;
}
Is there a way I could have one generic method that would take as a
parameter the item I wish returned?

Thank you for your help.
Al

Jan 25 '06 #8
I'm not sure that your example makes sense here... the original question was
to have a function where the main difference between calls was the type of
thingy (Flag, Cloth, etc). You've essentially written a version that will
*only* gets 1 type: X - i.e. very similar to the code in the OP. If you want
X to be variable, then (unless I'm being really, really slow) you *need*
this to be a generic - i.e. Get<X>

However! You do raise an interesting point; if I refactored this into a
standard TryGet format (but with generics), then I actually *don't* need to
specify T, since this will be inferred by the compiler (via the out param):

public static bool TryGet<T>(out T thingy) where T : Thingy {
lock(_Thingies) {
return _Thingies.TryGet(typeof(T), out thingy);
}
}

I should then be able to call

Flag f;
MyStaticClass.TryGet(out f);

This will then infer <Flag> since f is declared as <Flag>

Marc

Jan 25 '06 #9
(previous code didn't compile: this does)

public static bool TryGet<T>(out T thingy) where T : Thingy {
bool found;
Thingy foundItem;
lock (_Thingies) {
found = _Thingies.TryGetValue(typeof(T), out foundItem);
}
thingy = (T)foundItem;
return found;
}
Jan 25 '06 #10
Oh right, I see what you're doing; OK, further to the parallel post I'll
agree it does work - but it's a lot of repeated code, plus it makes the
calling symantecs a little tricker.

Personally, I'd rather have:

Flag f = MyStaticClass.Get<Flag>();

than either your or my version of:

Flag f;
MyStaticClass.Get(out f);

Marc
Jan 25 '06 #11
acb
Thank you to everyone for your input; you've help me learn (still to
fully understand :-) somthing new.

Jan 25 '06 #12
acb,
As the others have shown you can define a method with a parameterized return
type.

However! You need to supply the type parameter when you call the method
directly, something like:

object o = doSomething<object>();
MemoryStream m = doSomething<MemoryStream>();

Further! it "violates" an FxCop rule as its "ambiguous". The compiler is not
able to use Type Inference to figure out the type parameter...

Here is a thread that discusses it:

http://groups.google.com/group/micro...4e46ca8f99b798

Personally I find in the case of GetCustomAttribute (as the thread shows) it
makes sense as the type parameter is encapsulating the downcast, plus the
type parameter is used to "do work".

--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net
"acb" <ch******@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
| Hi,
|
| I have a list of different objects in a <List> Structure. There is only
| one category of each kind of object.
|
| Current I have the following methods:
|
| public static Flag GetFlagObj()
| {
| foreach (Thingy s in _Thingies)
| {
| if (s is Flag)
| return (Flag)s;
| }
| return null;
| }
|
| public static Cloth GetFlagObj()
| {
| foreach (Thingy s in _Thingies)
| {
| if (s is Cloth)
| return (Cloth)s;
| }
| return null;
| }
|
| public static BedSprd GetFlagObj()
| {
| foreach (Thingy s in _Thingies)
| {
| if (s is BedSprd)
| return (BedSprd)s;
| }
| return null;
| }
|
|
| Is there a way I could have one generic method that would take as a
| parameter the item I wish returned?
|
| Thank you for your help.
| Al
|
Jan 26 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Jim Newton | last post: by
49 posts views Thread by Steven Bethard | last post: by
8 posts views Thread by JAL | last post: by
5 posts views Thread by Metaman | last post: by
4 posts views Thread by Charles Churchill | last post: by
3 posts views Thread by kim.nolsoee | last post: by
26 posts views Thread by raylopez99 | last post: by
reply views Thread by =?Utf-8?B?TW9ydGVuIFdlbm5ldmlrIFtDIyBNVlBd?= | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.