Generic method to return object reference

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • acb

    Generic method to return object reference

    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

  • Joanna Carter [TeamB]

    #2
    Re: Generic method to return object reference

    "acb" <chribonn@gmail .com> a écrit dans le message de news:
    1138179819.5038 96.136590@g47g2 00...legr oups.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



    Comment

    • Vladimir Matveev

      #3
      Re: Generic method to return object reference

      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(dele gate(object obj)
      {
      return t.IsAssignableF rom(obj.GetType ());
      });
      }

      Comment

      • Marc Gravell

        #4
        Re: Generic method to return object reference

        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 ArgumentNullExc eption("thingy" ); // need a
        non-null thingy to call GetType()
        lock(_Thingies) {
        _Thingies.Add(t hingy.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(t ypeof(T), thingy);
        }
        }

        (or something like that; code not tested)

        Marc


        Comment

        • Vladimir Matveev

          #5
          Re: Generic method to return object reference

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

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

          Comment

          • Marc Gravell

            #6
            Re: Generic method to return object reference

            not important, but I omitted a useful where clause:

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

            Marc


            Comment

            • Joanna Carter [TeamB]

              #7
              Re: Generic method to return object reference

              "Marc Gravell" <mgravell@rm.co m> a écrit dans le message de news:
              emxnzPZIGHA.269 6@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


              Comment

              • Nick Hounsome

                #8
                Re: Generic method to return object reference

                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" <chribonn@gmail .com> wrote in message
                news:1138179819 .503896.136590@ g47g2000cwa.goo glegroups.com.. .[color=blue]
                > 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
                >[/color]


                Comment

                • Marc Gravell

                  #9
                  Re: Generic method to return object reference

                  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.TryGe t(typeof(T), out thingy);
                  }
                  }

                  I should then be able to call

                  Flag f;
                  MyStaticClass.T ryGet(out f);

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

                  Marc



                  Comment

                  • Marc Gravell

                    #10
                    Re: Generic method to return object reference

                    (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.TryGe tValue(typeof(T ), out foundItem);
                    }
                    thingy = (T)foundItem;
                    return found;
                    }


                    Comment

                    • Marc Gravell

                      #11
                      Re: Generic method to return object reference

                      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.G et<Flag>();

                      than either your or my version of:

                      Flag f;
                      MyStaticClass.G et(out f);

                      Marc


                      Comment

                      • acb

                        #12
                        Re: Generic method to return object reference

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

                        Comment

                        • Jay B. Harlow [MVP - Outlook]

                          #13
                          Re: Generic method to return object reference

                          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<obj ect>();
                          MemoryStream m = doSomething<Mem oryStream>();

                          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:



                          Personally I find in the case of GetCustomAttrib ute (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" <chribonn@gmail .com> wrote in message
                          news:1138179819 .503896.136590@ g47g2000cwa.goo glegroups.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
                          |


                          Comment

                          Working...