- Code: Select all
use System.Linq
extend IEnumerable<of T>
def cast<of R> as IEnumerable<of R>
return Enumerable.cast<of R>(this) to !
class Example
def main
list = [[0, 1], [1, 2], [2, 3]]
enumerable = list.cast<of IEnumerable<of int>>
This generates an exception from the underlying compiler after the C# code generation phase:
- Code: Select all
paramtest.cobra(10): error: The type arguments for method "Extend_IEnumerable__T__paramtest.Cast<T,R>(System.Collections.Generic.IEnumerable<T>)" cannot be inferred from the usage. Try specifying the type arguments explicitly
This appears to be because the resulting call to the generated extension method relies entirely upon implicit parameterization, based on looking at the intermediary C#:
- Code: Select all
enumerable=(Extend_IEnumerable__T__paramtest.Cast(list));
Since the type parameter being passed in is not indicated by the type of an argument to the extension method, it's not being implicitly specified and the C# compiler can't know what it is.
My question then is, is this an unimplemented piece, or an intentional limitation on what extension methods are capable of? I will certainly give you that it is a corner case to some degree (since usually, you don't have type parameters without arguments), but it certainly could come up.
The larger ramifications of not being able to specify type arguments could impact other things as well, I would think, such as a possible multiple-inheritance-esque situation with extended interfaces, like such:
- Code: Select all
interface IHasValue<of T>
def concat(v0 as T, v1 as T) as T
class StringIntClass implements IHasValue<of String>, IHasValue<of int>
def concat(v0 as String, v1 as String) as String
return v0 + v1
def concat(v0 as int, v1 as int) as int
return v0 + v1
extend IHasValue<of T>
def extendedMethod(v0 as T, v1 as T) as T
return .concat(v0, v1)
class Example
def main
print StringIntClass().extendedMethod(0, 1) # Example line 1
print StringIntClass().extendedMethod("one", "two") # Example line 2
In this example, if you try to call the first example line above, you get a compile-time error saying that the method takes string arguments, but if you try to call the second example line above, you get an error that the type arguments can't be inferred.
What this all boils down to is more-or-less that I'm wondering what the future of extensions and parameterized types is, partially out of my own curiosity (because I don't necessarily need to use any of the examples here), and partially because I did some digging and put some thought into how it works now, and how it might work. Thanks!