[BUG] Some problems with extension methods
I have encountered some problems while using extension methods, summarizing:
-
FIXED ~~
fordoesn't work even thoughTListhasIEnumerableconstraint.~~ - Extension methods declared as mixin doesn't work at all. (PS: If this isn't a bug, you can leave it as it is if you want, no worries)
- Crash while typing a delegate.
- FIXED ~~Compiler can't find an extension method if something with the same name already exists in the class.~~
-
FIXED ~~You have to cast the delegate to successfully call the
Count2method.~~
Here is the code with all the mentioned problems (commented out):
using System;
using System.Collections;
static
{
public static mixin CountMixin<TList, TValueType>(this TList list, delegate bool(TValueType) comparer)
where TList : IEnumerable<TValueType>
{
list.Count2(comparer)
}
public static int Count<TList, TValueType>(this TList list, delegate bool(TValueType) comparer)
where TList : IEnumerable<TValueType>
{
return list.Count2(comparer);
}
public static int Count2<TList, TValueType>(this TList list, delegate bool(TValueType) comparer)
where TList : IEnumerable<TValueType>
{
int count = 0;
// ERROR: Type 'TList' must contain a 'GetEnumerator' method or implement an IEnumerator<T> interface
//for (let item in list)
for (let item in list.GetEnumerator())
{
if (comparer(item))
count++;
}
return count;
}
}
namespace test5
{
class Program
{
public static int Main(String[] args)
{
int n = 0;
List<int> test = scope .();
test.Add(10);
test.Add(11);
test.Add(10);
// ERROR: Cannot find mixin
//n = test.CountMixin!(scope (x) => x == 10);
// CRASH: To reproduce, try to add a 0 in the end of the next line
//n = test.Count((delegate bool(int)) scope (x) => x == 10
// ERROR: Cannot perform invocation on type 'int'
//n = test.Count(scope (x) => x == 10);
// ERROR: Unable to determine generic argument 'TValueType'
//n = test.Count2(scope (x) => x == 10);
// Works fine
n = test.Count2((delegate bool(int)) scope (x) => x == 10);
Runtime.Assert(n == 2);
return 0;
}
}
}
Issue 1 fixed at https://github.com/beefytech/Beef/commit/9510faafca9f6d5119eb104f79d1c964b356a8e6. You also have to add the new concrete constraint to TList.
On issue 5- this also doesn't work in C#. This would require that the compiler examine the lambda code and decide that x == 10 probably means that you want x to be an int. That's not the kind of inference we can (nor do I think should) do.
Oh wait actually I misread this example.
Ok, 5 is also fixed actually, too.
public static int Count2<TList, TValueType>(this TList list, delegate bool(TValueType) comparer)
where TList : concrete, IEnumerable<TValueType>
{
int count = 0;
for (let item in list)
{
if (comparer(item))
count++;
}
return count;
}
I just noticed something, with the latest IDE version, the (unmodified) code of this issue shows an error in the IDE but compiles fine.

The enumeration issue above should be fixed in the next nightly.