Author Topic: Method that returns 2 types  (Read 2267 times)

0 Members and 1 Guest are viewing this topic.

BillZndl

  • Guest
Method that returns 2 types
« on: September 01, 2011, 06:54:53 AM »
I have a method that opens the entities in an ObjectId[] for read.
Then gets points from each entity and returns an Arraylist of point3d[]'s.

I also need a List<string> of layer names to display color of the entity.
I could get the list of layer names at the same time that I read the entity for points.

Might be a dumb question but what is or is there a best way to return an Arraylist and a List<string> instead of running one method to get the points then another, almost identical method, to get the Layer list of strings?

If the only way is to run two methods, that is fine but I have a feeling there is a better way to do this.  :|

TIA.


jgr

  • Guest
Re: Method that returns 2 types
« Reply #1 on: September 01, 2011, 07:33:10 AM »
Code: [Select]
void zzz(ObjectId[] ids, ref List<string> layers, ref ArrayList points) { }http://msdn.microsoft.com/en-us/library/14akc2c7.aspx

Code: [Select]
Private Sub zzz(ByVal ids() As ObjectId, ByRef layers As List(Of String), ByRef points As ArrayList)
End Sub
http://msdn.microsoft.com/en-us/library/c84t73c2.aspx

gile

  • Gator
  • Posts: 2516
  • Marseille, France
Re: Method that returns 2 types
« Reply #2 on: September 01, 2011, 08:25:54 AM »
Hi,

Another way is to define a little class with 2 properties of types: Point3d[] and List<string>.

Then return an instance of this class from your method.

Code: [Select]
    class PointsAndLayers
    {
        public Point3d[] Points { get; set; }
        public List<string> Layers { get; set; }
    }

// ...

        private PointsAndLayers GetPointsAndLayers(ObjectId[] ids)
        {
            //...
            Point3d[] points = new Point3d[ids.Length];
            List<string> layers = new List<string>(ids.Length);
            //...
                for (int i = 0; i < ids.Length; i++)
                {
                    /...
                    points[i] = point;
                    layers.Add(layer);
                }
                //...
            }
            return new PointsAndLayers { Points = points, Layers = layers };
        }
Speaking English as a French Frog

zoltan

  • Guest
Re: Method that returns 2 types
« Reply #3 on: September 01, 2011, 08:32:48 AM »
gile has the best way, because it would give higher meaning to the values and you can put additional implementation into the class to do specific things with instances of the object.  But if you are lazy, you can use a System.Tuple (in .NET 4.0), which is just a generic class for a group of 2 to 8 values.

Code: [Select]
        private Tuple<Point3d[], List<string>> GetPointsAndLayers(ObjectId[] ids)
        {
            //...
            Point3d[] points = new Point3d[ids.Length];
            List<string> layers = new List<string>(ids.Length);
            //...
                for (int i = 0; i < ids.Length; i++)
                {
                    /...
                    points[i] = point;
                    layers.Add(layer);
                }
                //...
            }
            return new Tuple<Point3d[], List<string>>(points , layers);
        }

BillZndl

  • Guest
Re: Method that returns 2 types
« Reply #4 on: September 01, 2011, 09:11:02 AM »
jgr:

Works great! Almost too good to be true!  :laugh:
Thanks.

gile:

Great example! Never thought of doing it with a separate class containing properties.   :-D

zoltan:

Wow, something new to make things simpler.
I'm using net 3.5 at the moment but will keep that one in mind for future use.  8-)

Thanks all.







Jeff H

  • Needs a day job
  • Posts: 6150
Re: Method that returns 2 types
« Reply #5 on: September 01, 2011, 10:50:13 AM »
Here is an example using Tuples
 
http://www.theswamp.org/index.php?topic=37061.msg421047#msg421047
 
I am sure there are better examples by kaefer since I believe it was introduced because of F# but can not read F# well enough.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8753
  • AKA Daniel
Re: Method that returns 2 types
« Reply #6 on: September 01, 2011, 11:07:43 AM »
another way

Code: [Select]
using System;
using Duple = System.Collections.Generic.KeyValuePair<System.Int32,System.Int32>; //<<<------------
namespace ExecMethod
{
  public class Commands
  {
    Duple returnTwoThingies()
    {
      return new Duple(45, 99);
    }
  }
}
« Last Edit: September 01, 2011, 11:18:20 AM by __assume »

gile

  • Gator
  • Posts: 2516
  • Marseille, France
Re: Method that returns 2 types
« Reply #7 on: September 01, 2011, 01:10:08 PM »
Tuples are certainly more usefull and powerfull with F#.

They can be used to bind many symbols at one time:
Code: [Select]
let (a, b, c) = (12, 3.14, "foo")instead of:
Code: [Select]
int a = 12;
double b = 3.14;
string c = "foo"

They can be used to return multiple values (as shown upper):
Code: [Select]
let divRem a b = (a / b, a % b)C#:
Code: [Select]
Tuple<int, int> DivRem(int a, int b)
{
    return new Tuple<int, int>(a / b, a % b);
}

To access a tuple value, with F#, you can use the fst or snd functions;
Code: [Select]
let dr = divRem 27 5 // (5, 2)
let d = fst dr //  5
let r = snd dr // 2
withC# the Item1 and Item2 properties
Code: [Select]
Tuple<int, int> dr = DivRem(27 5); // <5, 2>
int d = dr.Item1; // 5
int r = dr.Item2; // 2
Speaking English as a French Frog

kaefer

  • Guest
Re: Method that returns 2 types
« Reply #8 on: September 01, 2011, 04:40:24 PM »
So far we have:
ref parameter modifier
void zzz(ObjectId[] ids, ref List<string> layers, ref ArrayList points) { }
separate class/struct
class PointsAndLayers
{
    public Point3d[] Points { get; set; }
    public List<string> Layers { get; set; }
}
//...
return new PointsAndLayers { Points = points, Layers = layers };
System.Tuple
return new Tuple<Point3d[], List<string>>(points , layers);
predefined class/struct
using Duple = System.Collections.Generic.KeyValuePair<System.Int32,System.Int32>;
//...
return new Duple(45, 99);

Then there is out, like ref, but without the need to initialize it. And for completeness' sake, passing a plain collection object in order to mutate it inside your function.

out parameter modifier
ArrayList getPoints(ObjectId[] ids, out string[] layers) { }
collection object
string[] getLayers(ObjectId[] ids, points) {
    points.Add(...);
}
//...
Arraylist points = new ArrayList();
var res = getLayers(ids, points);
« Last Edit: September 01, 2011, 04:45:50 PM by kaefer »

kaefer

  • Guest
Re: Method that returns 2 types
« Reply #9 on: September 01, 2011, 04:59:59 PM »
Tuples are certainly more usefull and powerfull with F#.

They can be used to store the return values of library functions with out parameters. E.g.
public static bool TryParse(string s, out int result):

Code: [Select]
let (ok, res) = System.Int32.TryParse "1234"
if ok then
    // conversion successful, do something with res

Glenn R

  • Guest
Re: Method that returns 2 types
« Reply #10 on: September 05, 2011, 07:22:07 AM »
Dictionary.