# Delegate as Method Parameter

**URL:** <https://forum.xojo.com/t/delegate-as-method-parameter/13638>\
**Category:** General\
**Created:** [January 15, 2014, 3:50pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638 "2014-01-15T15:50:31Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 15, 2014, 3:50pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/1 "2014-01-15T15:50:31Z")

</div>

I know something like this is possible but I’m curious as how to properly implement this.

I want a parameter of a method to accept a method delegate.  
I want this method to call the delegate method multiple times.  
I want the delegate method to return a boolean value.  
I want the delegate method to accept one Object parameter.

I’m mostly not sure how to restrict the delegate type passed and properly invoke it.

What I’m going for is something like this:

```auto
dim arrayList2 = arrayList.Where( AddressOf MyCondition)
```

And have two methods something like this:

[code]Sub Select(extends o2() as object, d as delegate)  
dim r() as Object  
For i as integer = 0 to o.Ubound  
if /\* Invoking Delegate on o(i) is true \*/ then  
r.Append(o(i))  
end  
Next  
return r  
End Sub

Sub MyCondition(o as Object) as boolean  
//some operations on o that returns true or false  
End Sub  
[/code]

---

<div class="post-metadata">

**Author:** ![Christian\_Schmitz](https://forum.xojo.com/user_avatar/forum.xojo.com/christian_schmitz/32/158_2.png) [@Christian\_Schmitz](https://forum.xojo.com/u/Christian_Schmitz)\
**Post date:** [January 15, 2014, 4:03pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/2 "2014-01-15T16:03:46Z")

</div>

First create your global delegate for this in a module and don’t name it just " delegate"  
Than you can use that as parameter.

now in if you can use

if d(o(i)) then

if delegate is declared with the declaration:

MyDelegate(o as Object) as boolean

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 15, 2014, 4:17pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/3 "2014-01-15T16:17:40Z")

</div>

There’s something not quite right

My Delegate:

`Delegate Function DelegateCondition(o as Object) As Boolean
`

My Where Method

[code]Function Where(extends o() as Object, delegatePtr as ptr) As Object()  
dim d as new DelegateCondition(delegatePtr)  
dim r() as Object

for i as integer = 0 to o.Ubound  
dim b as Boolean  
dim o1 as Object = o(i)  
if d.invoke(o1) then  
r.Append(o1)  
end  
Next  
return r  
End Function  
[/code]

But when compiling I get the Error on:

```auto
 dim d as new DelegateCondition(delegatePtr)
```

It says External functions cannot use objects as parameters

Thoughts?

---

<div class="post-metadata">

**Author:** ![Christian\_Schmitz](https://forum.xojo.com/user_avatar/forum.xojo.com/christian_schmitz/32/158_2.png) [@Christian\_Schmitz](https://forum.xojo.com/u/Christian_Schmitz)\
**Post date:** [January 15, 2014, 4:27pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/4 "2014-01-15T16:27:32Z")

</div>

leave the line away.  
you must declare the function with

Function Where(extends o() as Object, d as DelegateCondition) As Object()

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 15, 2014, 5:57pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/5 "2014-01-15T17:57:15Z")

</div>

Perfect!

Thank you very much Christian, I’ll see you at the Xojo Conference!

I’m building a library I call Fauxlinq which is based on concepts from linq (C#).

Essentially you can take any array of objects and do stuff like this:

`dim myContactsAtLocation() as Contacts
allContactsArray.Where("Company.Address.Zip", "=", 58078).Where(AddressOf someConditionMethod).OrderBy(Company.Name).Limit(10).SelectInto(myContactsAtLocation)
`  
Eventually I want to add support for Joins and even sql queries!

Introspection currently follows the . notation properly to access property but I want to add support for array elements too. Something like Contacts.Company(5).Address.Zip

---

<div class="post-metadata">

**Author:** ![Norman\_P](https://forum.xojo.com/letter_avatar_proxy/v4/letter/n/858c86/32.png) [@Norman\_P](https://forum.xojo.com/u/Norman_P)\
**Post date:** [January 15, 2014, 7:34pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/6 "2014-01-15T19:34:09Z")

</div>

By extending Object you’re going to lose the type safety the language provides

You will probably be able to write

`dim something as Timer
something.Where("Company.Address.Zip", "=", 58078).Where(AddressOf SomeConditionMethod).OrderBy(Company.Name).Limit(10).SelectInto(myContactsAtLocation)
`  
And it will sort of make some measure of “sense” as it will all compile but give you completely bogus results

You’ll get “safety” by convention not by design

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 15, 2014, 8:18pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/7 "2014-01-15T20:18:19Z")

</div>

> [@59253:@Norman Palardy](#):
>
> By extending Object you’re going to lose the type safety the language provides

The methods only extend an array of objects. So:

`dim something as Timer
something.Where(...)`  
Would not work. But:

`dim someThings() as Timer
someThings.Where(...)`  
Would work

I think this is desirable and safeguards the convention.

---

<div class="post-metadata">

**Author:** ![Christian\_Schmitz](https://forum.xojo.com/user_avatar/forum.xojo.com/christian_schmitz/32/158_2.png) [@Christian\_Schmitz](https://forum.xojo.com/u/Christian_Schmitz)\
**Post date:** [January 15, 2014, 8:20pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/8 "2014-01-15T20:20:02Z")

</div>

you could overload the method with a lot of possible class names.  
maybe even write code generator to create all the combinations.

---

<div class="post-metadata">

**Author:** ![Norman\_P](https://forum.xojo.com/letter_avatar_proxy/v4/letter/n/858c86/32.png) [@Norman\_P](https://forum.xojo.com/u/Norman_P)\
**Post date:** [January 15, 2014, 10:11pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/9 "2014-01-15T22:11:55Z")

</div>

Instead of extends methods on “object” I’d define an interface then extend the interface  
That way it’s less likely to do something unintentional and you get some measure of type safety from the compiler

You add the interface (with no methods) to whatever classes yo want to use this with

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 15, 2014, 10:44pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/10 "2014-01-15T22:44:54Z")

</div>

[quote=59276:@Christian Schmitz]you could overload the method with a lot of possible class names.  
maybe even write code generator to create all the combinations.[/quote]

Its nice that this already works with arrays of any object but it unfortunately doesn’t work with primitives. Instead of creating an overloaded method for every different single primitive, is there a better way.

Currently all I can think of as writing a single extends methods per primitive that converts an array of it into an array of variants.

As far as adding support for things besides Arrays, I know I definitely want SQLQuery implementation but I’m not sure what other classes it would make sense to implement this for besides those two… Maybe Json/XML?

[quote=59308:@Norman Palardy]Instead of extends methods on “object” I’d define an interface then extend the interface  
That way it’s less likely to do something unintentional and you get some measure of type safety from the compiler

You add the interface (with no methods) to whatever classes yo want to use this with[/quote]

I guess I’m not sure how the interface would work then. The point of having it Extend on an array of Objects and return an Array of objects is so you can do consecutive “.” functions on it in a single line. This works with any array and doesn’t need to know about the classes ahead of time because it uses introspection. Having to write implementation for every class that has to use this would defeat the purpose. I’m building this so that anywhere in code on any array I can quickly filter the array without needing loops or nesting.

---

<div class="post-metadata">

**Author:** ![Norman\_P](https://forum.xojo.com/letter_avatar_proxy/v4/letter/n/858c86/32.png) [@Norman\_P](https://forum.xojo.com/u/Norman_P)\
**Post date:** [January 15, 2014, 11:47pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/11 "2014-01-15T23:47:03Z")

</div>

You can extend an interface because an interface IS a type (same as Object) BUT YOU would control what can / cannot be used with your classes a lot better & the compiler could flag errors

And you DONT have to write any implementations - you just want something more type safe than “Object”

The reason

`dim someThings() as Timer
someThings.Where()
`  
Makes virtually no sense in any context so why not get the compiler to help you where it can

Try this

1. create an interface “LinqObject” - don’t need methods etc JUST need the type
2. to ANY class you want to participate in this you add the interface
3. change your code to use LinqObject instead of Object

run  
Anything that is NOT a LinqObject will no longer work

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 16, 2014, 4:00am UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/12 "2014-01-16T04:00:16Z")

</div>

[quote=59329:@Norman Palardy]`dim someThings() as Timer
someThings.Where()`  
Makes virtually no sense in any context so why not get the compiler to help you where it can  
[/quote]

Of course this example doesn’t make much sense because someThings is an empty array.  
But lets say I have an array of all of my timers.  
And I wanted to do something to just my timers that were active

```auto
myTimers.Where("Enabled", "=", true).SelectInto(myActiveTimers)
```

It provides a quick and easy way to filter down an Array.  
I use this every day in C# and I wanted something in Xojo to replicate how it works. While it may seem like a silly concept from an outside perspective its darn right convenient. Granted it is much more convenient in C# because C# supports lambda expression

```auto
var blarg = Contacts.Where( c => c.Age < 30 && c.Age > 20 && c.IsMale == true).Limit(5)
```

This works on lists, arrays, dictionaries, IQueryables, IEnumarables etc…  
Of course this is an interface in C#. But the core framework supports this, which is something I cannot do hence the extends keyword coming into play. I definitely will include an interface for this, but in the case of dictionaries and arrays I have little choice but to use extends.

If I were to have two additional features in Xojo it would be lambda expressions and the generic type parameter. In fact generic type parameters is something VisualBasic supports as well.  
[link text](http://msdn.microsoft.com/en-us/library/w256ka79.aspx)

These concepts exist in other languages for a reason. Christian’s mention of “maybe even write code generator to create all the combinations.” would be irrelevant if Generic Types were supported.

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 16, 2014, 4:31am UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/13 "2014-01-16T04:31:03Z")

</div>

I’m wondering if the solution would to just build one extension method that converts an array of objects into a custom linq class, and have that linq class implement the interface.

Something like:

```auto
dim myTimers() as timer
dim myActiveTimers() as timer
//fill myTimer array
myTimers.fauxlinq.Where("Enabled", "=", true).SelectInto(myActiveTimers)
```

That would also allow the Autofill to work once “fauxlinq” it.  
I’m thinking this might be a better way. Is this kind of what you meant @Norman Palardy ?

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 16, 2014, 4:58am UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/14 "2014-01-16T04:58:39Z")

</div>

Scratch that, I’m getting an error that “extends modifier cannot be used on a class method” so there’s no point in the interface since “.” notation wont be valid and this:

```auto
SelectInto(Limit(OrderBy(Where(myArray, AddressOf myCondition), "Age"), 5), myFilteredArray)
```

Looks HORRIBLE  
compared to:

```auto
myArray.Where(AddressOf myCondition).OrderBy("Age").Limit(5).SelectInto(myFilteredArray)
```

---

<div class="post-metadata">

**Author:** ![Norman\_P](https://forum.xojo.com/letter_avatar_proxy/v4/letter/n/858c86/32.png) [@Norman\_P](https://forum.xojo.com/u/Norman_P)\
**Post date:** [January 16, 2014, 7:34am UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/15 "2014-01-16T07:34:43Z")

</div>

[quote=59350:@Brock Nash]Of course this example doesn’t make much sense because someThings is an empty array.  
But lets say I have an array of all of my timers.  
And I wanted to do something to just my timers that were active  
[/quote]  
With extends & object the way its set up you toss out all type safety the compiler might have been able to infer to help you out.  
I get WHY you want this but doing it with extends & object means that the ONLY way you can catch anything is to do 100% code coverage testing or just wait til bugs crop up at run time.

I like having the compiler help me where it can at compile time.

But this is your code to live with 🙂

---

<div class="post-metadata">

**Author:** ![Will\_Shank](https://forum.xojo.com/letter_avatar_proxy/v4/letter/w/f475e1/32.png) [@Will\_Shank](https://forum.xojo.com/u/Will_Shank)\
**Post date:** [January 16, 2014, 10:37am UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/16 "2014-01-16T10:37:55Z")

</div>

> [@59370:@Norman Palardy](#):
>
> With extends & object the way its set up you toss out all type safety the compiler might have been able to infer to help you out.

I don’t see this. These extends methods are defined for 1D Object arrays, that’s what they work on and the compiler will say if the type isn’t a 1D Object array. So the typing is strict, it’s just that it’s a very generic type.

Both ways have their pros: with an interface you can apply the feature to a narrow manually selected set, with Object the feature is ubiquitous and more RAD. But given one it’s simply a matter of replacing type to get the other (I think). You could develop a set of method templates having generic type and feed it a list of those types to autogenerate. Probably need two sets of templates, one for Object/iLinq and another for String, Single, Double, UInt8…

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 16, 2014, 2:38pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/17 "2014-01-16T14:38:42Z")

</div>

> [@59412:@Will Shank](#):
>
> Both ways have their pros: with an interface you can apply the feature to a narrow manually selected set, with Object the feature is ubiquitous and more RAD. But given one it’s simply a matter of replacing type to get the other (I think). You could develop a set of method templates having generic type and feed it a list of those types to autogenerate. Probably need two sets of templates, one for Object/iLinq and another for String, Single, Double, UInt8…

The problem with an interface as I discovered above is that you can’t use “extends”. This makes it pretty impractical to use.

Another issue right now is that autofill doesn’t work for these extended methods on object arrays. (Bug?)

I’m thinking that having a new set of templates for each primitive (string, single, double, etc…) is more work than it needs to be. Instead I’m planning on a single method that casts an array of these into an array of variants which counts as an array of objects.

---

<div class="post-metadata">

**Author:** ![Norman\_P](https://forum.xojo.com/letter_avatar_proxy/v4/letter/n/858c86/32.png) [@Norman\_P](https://forum.xojo.com/u/Norman_P)\
**Post date:** [January 16, 2014, 3:48pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/18 "2014-01-16T15:48:32Z")

</div>

> [@59447:@Brock Nash](#):
>
> The problem with an interface as I discovered above is that you can’t use “extends”.

Most certainly can - you can extend ANY type and an interface defines a type.  
Enter this into an IDE script & hit run  
Since IDE scripting use the same compiler & language you can test this out this way

[code] interface MyLinq  
end interface

class myClass  
implements myLinq  
end class

module myExtensions  
sub something( extends m as myLinq)  
print “hello world”  
end sub  
end module

dim c as myClass  
c = new myClass  
c.something[/code]

---

<div class="post-metadata">

**Author:** ![Brock\_Nash](https://forum.xojo.com/user_avatar/forum.xojo.com/brock_nash/32/1126_2.png) [@Brock\_Nash](https://forum.xojo.com/u/Brock_Nash)\
**Post date:** [January 17, 2014, 7:50pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/19 "2014-01-17T19:50:13Z")

</div>

[quote=59467:@Norman Palardy]Most certainly can - you can extend ANY type and an interface defines a type.  
Enter this into an IDE script & hit run  
Since IDE scripting use the same compiler & language you can test this out this way  
[/quote]

It didn’t work because I tried including the methods as part of the interface and then had the class try to implement those methods. To me this is how it should be done.

If the interface doesn’t say what methods to implement and the classes that implement that interface can’t have their own implementations of these methods then what is the point of having an interface?

---

<div class="post-metadata">

**Author:** ![Norman\_P](https://forum.xojo.com/letter_avatar_proxy/v4/letter/n/858c86/32.png) [@Norman\_P](https://forum.xojo.com/u/Norman_P)\
**Post date:** [January 17, 2014, 8:09pm UTC](https://forum.xojo.com/t/delegate-as-method-parameter/13638/20 "2014-01-17T20:09:21Z")

</div>

[quote=59747:@Brock Nash]It didn’t work because I tried including the methods as part of the interface and then had the class try to implement those methods. To me this is how it should be done.  
[/quote]  
Thats what I would do EXCEPT you can’t have an interface on an array which seems to be what you really want.  
What’d you define for the methods ?

> [@59747:@Brock Nash](#):
>
> If the interface doesn’t say what methods to implement and the classes that implement that interface can’t have their own implementations of these methods then what is the point of having an interface?

To define a type that you can extend  
Then the extensions can be very specifically targeted at things that implement the interface instead of just “Object”

[Next page](https://forum.xojo.com/t/delegate-as-method-parameter/13638.md?page=2)
