Results 1 to 16 of 16

Thread: [RESOLVED] sub returning diffrent types

  1. #1

    Thread Starter
    Fanatic Member Crash893's Avatar
    Join Date
    Dec 2005
    Posts
    930

    Resolved [RESOLVED] sub returning diffrent types

    Hey all.

    I two subs that are almost exactly identical that return two different types of control


    I would use the sub something like

    textbox1.text = stringtoMatchtype1("match1").chatter;

    where chatter is a property of matchtype1(and 2)

    I could just return a control but then i couldnt access the propertys and methods of that contorl.



    any ideas to point me down a better path?

    c# Code:
    1. private MatchType1 StringToMatchType1(string name)
    2.         {
    3.             foreach (TabPage tp in tabControl1.Controls)
    4.             {
    5.                 foreach (Control c in tp.Controls)
    6.                 {
    7.                     if (c is MatchType1)
    8.                     {
    9.                         if (c.Name == name)
    10.                         {
    11.                             return (MatchType1)c;
    12.                         }
    13.                     }
    14.                 }
    15.             }
    16.             throw new Exception("Matchtype1 not found" + name);
    17.         }
    18.         private MatchType2 StringToMatchType2(string name)
    19.         {
    20.             foreach (TabPage tp in tabControl1.Controls)
    21.             {
    22.                 foreach (Control c in tp.Controls)
    23.                 {
    24.                     if (c is MatchType2)
    25.                     {
    26.                         if (c.Name == name)
    27.                         {
    28.                             return (MatchType2)c;
    29.                         }
    30.                     }
    31.                 }
    32.             }
    33.             throw new Exception("Matchtype2 not found" + name);
    34.         }

  2. #2
    Hyperactive Member
    Join Date
    Mar 2002
    Location
    Boston, MA
    Posts
    391

    Re: sub returning diffrent types

    you could just make one method that returns the Control as it is and then cast it since you already know what the type is.

  3. #3

    Thread Starter
    Fanatic Member Crash893's Avatar
    Join Date
    Dec 2005
    Posts
    930

    Re: sub returning diffrent types

    i could but it seems like a lot extra repeat code

  4. #4
    Hyperactive Member
    Join Date
    Mar 2002
    Location
    Boston, MA
    Posts
    391

    Re: sub returning diffrent types

    i was proposing using one method and just searching by name. You could also use a generic method if you are using .net 3.5

    vb.net Code:
    1. private T FindControl<T>(string name)
    2.         {
    3.             foreach (Control c in this.Controls)
    4.             {
    5.                 if (c.Name == name && c is T)
    6.                 {
    7.                     Type retType = typeof(T);
    8.  
    9.                     return (T)Convert.ChangeType(c, retType);
    10.  
    11.                    
    12.                 }
    13.  
    14.             }
    15.  
    16.             return default(T);
    17.         }

    then if you're looking for a button do the following:

    Button b = FindControl<Button>("YourButtonName");

    You could also change this to a nongeneric method and return an object. Then cast appropriately. I don't think it's possible anyway to have a control of the same name so you shouldn't have trouble.

  5. #5
    Frenzied Member
    Join Date
    Sep 2005
    Posts
    1,547

    Re: sub returning diffrent types

    You could make MatchType an interface and then have MatchType1/MatchType2 inherit from it.

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: sub returning diffrent types

    There's no such thing as a "sub" in C#. That's a VB thing. In VB a Sub is a method that doesn't return a value and a Function is a method that does return a value. In C# all methods are functions. The C# equivalent of a VB Sub is a void function. That said, both your functions DO return something so they wouldn't be Subs in VB even.

    wy25 has the right of it, except that this is neater:
    CSharp Code:
    1. private T FindControl<T>(string name) where T:Control
    2. {
    3.     foreach (Control ctl in this.Controls)
    4.     {
    5.         if (ctl is T && ctl.Name == name)
    6.         {
    7.             return (T)ctl;
    8.         }
    9.     }
    10.  
    11.     return null;
    12. }
    You constrain T to inherit Control and then the compiler allows you to cast as T inside the method. You can also return null explicitly instead of using default because you know that any type that inherits Control must be a reference type.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7

    Thread Starter
    Fanatic Member Crash893's Avatar
    Join Date
    Dec 2005
    Posts
    930

    Re: sub returning diffrent types

    how is that any diffrent than just returning the type of control.

    i would still have to cast it as the type im expecting but now i just would do it where it was called rather than in the method itself


    i'm trying to avoid this because it leaves little nuggets of repeat code all over the place.

  8. #8
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: sub returning diffrent types

    what? You wouldn't need to cast it... it would already be done as part of <T> .... you specify the type you are looking for on the way in.... the object that comes out (if not NULL) will be of that type.

    And what "nuggets of repeat code" are you going on about?

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  9. #9
    Hyperactive Member syntaxeater's Avatar
    Join Date
    Dec 2006
    Location
    Des Moines, IA
    Posts
    460

    Re: sub returning diffrent types

    This work for you?
    Code:
            private MatchType1 FindControl(string value) 
            {
                return this.Controls.OfType<MatchType1>().Where(c => c.chatter == value).FirstOrDefault();
            }

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: sub returning diffrent types

    Quote Originally Posted by syntaxeater
    This work for you?
    Code:
            private MatchType1 FindControl(string value) 
            {
                return this.Controls.OfType<MatchType1>().Where(c => c.chatter == value).FirstOrDefault();
            }
    That's a a nice use of LINQ that leads to some concise code. To combine the generic method suggested by by wy125, the constraint suggested by myself and the LINQ suggested by syntaxeater:
    CSharp Code:
    1. public T FindControl<T>(string name) where T : Control
    2. {
    3.     return this.Controls.OfType<T>().Where(c => c.Name == name).FirstOrDefault();
    4. }
    Now you can use that method to return a control of any specific type with a specific name.

    As tg said, the whole point of generics is to be able to use the same code for many different types. This method returns a reference of type T where YOU specify what T is when you call the method. If you call the method like this:
    CSharp Code:
    1. this.FindControl<MatchType1>("something");
    then the method will return a reference of type MatchType1. If you call it like this:
    CSharp Code:
    1. this.FindControl<MatchType2>("something");
    then it will return a reference of type MatchType2. If you call it like this:
    CSharp Code:
    1. this.FindControl<Button>("something");
    then it will return a reference of type Button.

    If you use a List<T> do you have to cast the items as you get them? Of course not. You specify what T is when you create the List and then every item you get from the List is that type. There's no need to cast. Generic methods are the same. You fix T when you call the method and then every use of T in the method becomes that type. In this case the return type of the method is T, so if you fix T to be Button then the return type of the method becomes Button. Etc.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  11. #11
    Hyperactive Member
    Join Date
    Mar 2002
    Location
    Boston, MA
    Posts
    391

    Re: sub returning diffrent types

    that's pretty cool guys. I've learned something new...

  12. #12
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: sub returning diffrent types

    I should actually point out an error in my earlier terminology that many people make. The code that syntaxeater provided earlier and I modified doesn't actually use LINQ per se. It uses extension methods and lambda expressions directly. They are both language features that were added to support LINQ but their use is not limited to LINQ exclusively. There's no actual LINQ query in that code so it's not actually LINQ. It's still pretty cool code, but an actual LINQ implementation would have to contain an actual query, with a 'where' clause rather than a call to the Where method. Of course, such a query would be implemented in much the same way as the code provided.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  13. #13
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: sub returning diffrent types

    Here's the equivalent using an actual LINQ query:
    CSharp Code:
    1. public T FindControl<T>(string name) where T : Control
    2. {
    3.     return (from t in this.Controls.OfType<T>()
    4.             where t.Name == name
    5.             select t).FirstOrDefault();
    6.  
    7. }
    As far as I'm aware the OfType and FirstOrDefault calls can't be folded into the query syntax in any way.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  14. #14

    Thread Starter
    Fanatic Member Crash893's Avatar
    Join Date
    Dec 2005
    Posts
    930

    Re: sub returning diffrent types

    Quote Originally Posted by jmcilhinney
    I should actually point out an error in my earlier terminology that many people make. The code that syntaxeater provided earlier and I modified doesn't actually use LINQ per se. It uses extension methods and lambda expressions directly. They are both language features that were added to support LINQ but their use is not limited to LINQ exclusively. There's no actual LINQ query in that code so it's not actually LINQ. It's still pretty cool code, but an actual LINQ implementation would have to contain an actual query, with a 'where' clause rather than a call to the Where method. Of course, such a query would be implemented in much the same way as the code provided.

    i see now

    I will try this out and let you know

    Thanks

  15. #15
    Hyperactive Member syntaxeater's Avatar
    Join Date
    Dec 2006
    Location
    Des Moines, IA
    Posts
    460

    Re: sub returning diffrent types

    Quote Originally Posted by jmcilhinney
    Here's the equivalent using an actual LINQ query:
    CSharp Code:
    1. public T FindControl<T>(string name) where T : Control
    2. {
    3.     return (from t in this.Controls.OfType<T>()
    4.             where t.Name == name
    5.             select t).FirstOrDefault();
    6.  
    7. }
    As far as I'm aware the OfType and FirstOrDefault calls can't be folded into the query syntax in any way.
    OfType - There is a way, but not one more concise than what has been previously suggested:
    Code:
            public T FindControl<T>(string name) where T : Control
            {
                return (T)(from Control t in this.Controls
                           where t.GetType() == typeof(T) && t.Name == name
                           select t).FirstOrDefault();
            }
    However, using Extension OfType is by far a nicer means (in my opinion).

    FirstOrDefault - no, you can't. The query will not execute until one of the Linq.Enumerable members that produces a result has been called. As far as I am aware, there's no way for it to change the return type based on an anticipated number of results from the expression alone.

  16. #16
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: sub returning diffrent types

    Quote Originally Posted by syntaxeater
    OfType - There is a way, but not one more concise than what has been previously suggested:
    Code:
            public T FindControl<T>(string name) where T : Control
            {
                return (T)(from Control t in this.Controls
                           where t.GetType() == typeof(T) && t.Name == name
                           select t).FirstOrDefault();
            }
    However, using Extension OfType is by far a nicer means (in my opinion).

    FirstOrDefault - no, you can't. The query will not execute until one of the Linq.Enumerable members that produces a result has been called. As far as I am aware, there's no way for it to change the return type based on an anticipated number of results from the expression alone.
    I was thinking of a specifically LINQ way to replace the OfType call, which there isn't. Certainly there's nothing wrong with testing the type in the 'where' clause but it does then require casting the result before returning, as you've done. If I was going to test the type in the 'where' clause I'd do it with the 'is' operator:
    CSharp Code:
    1. public T FindControl<T>(string name) where T : Control
    2. {
    3.     return (T)(from Control t in this.Controls
    4.                where t is T && t.Name == name
    5.                select t).FirstOrDefault();
    6. }
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width