By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,145 Members | 1,552 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,145 IT Pros & Developers. It's quick & easy.

Generic method to return object reference

P: n/a
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
Share this Question
Share on Google+
12 Replies


P: n/a
"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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
not important, but I omitted a useful where clause:

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

Marc
Jan 25 '06 #6

P: n/a
"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

P: n/a
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

P: n/a
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

P: n/a
(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

P: n/a
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

P: n/a
acb
Thank you to everyone for your input; you've help me learn (still to
fully understand :-) somthing new.

Jan 25 '06 #12

P: n/a
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.