Is it possible to define extension methods for parameterized generic types in F# (like in C#)
F# has a mechanism for defining extensions that is "C#-compatible", and your use case is specifically called out, check here.
Something like this should work:
open System.Collections.Generic
open System.Runtime.CompilerServices
[<Extension>]
type Extensions =
[<Extension>]
static member inline ContainsTest(xs: List<int>, s: int) =
xs.Contains(s)
Can't write CLI-Compatible Extension Methods in F#
@dumetrulo in the comment had the solution here. The extension methods need to be let-bound functions in a module, without the enclosing type declaration:
namespace Extensions
open System
open System.Runtime.CompilerServices
[<Extension>]
module Extensions =
[<Extension>]
let Print(str : System.String) = Console.WriteLine(str)
[<Extension>]
let Blorp(o : System.Object) = Console.WriteLine("Hello World from an F# Extension Method!")
Additionally, the [<assembly: Extension>]
attribute appears to be unnecessary
Difference between `where` in the query object and `if` in the extension methods
I prediction the exact speed difference between them. if
is faster. But for legibility reasons, where is the most commonly used route. You can understand where
like a sql
query. Here, it filters some data from the data collection and reveals the ones that are suitable for you. Looks like T-Sql
.
Extension Methods on Properties in C#
Are you trying to avoid needing to call the get
and the set
separately? It would work to use just a normal extension method like
public Vector MoveX(this Vector prop, float val){...}
and then you would use it like
myLine.start = myLine.start.MoveX(2f);
Is that still more complicated than what you would want to do? If so, you could make a public method that calls the get
and set
for you and you just supply the float that you want to move by.
public void MoveStartX(float x){...}
public void MoveEndX(float x){...}
Solution using reflection... is it worth it?
If you are wanting a very generic extension that works using reflection and doesn't have to specifically use a Line
object, you could do the following
public static void MoveX<T>(this T obj, Expression<Func<T, Vector>> lambda, float x)
{
if (lambda.Body is MemberExpression memberExpression)
{
var propertyInfo = (PropertyInfo)memberExpression.Member;
var getMethod = propertyInfo.GetGetMethod();
var setMethod = propertyInfo.GetSetMethod();
if (setMethod == null || getMethod == null)
throw new ArgumentException("lambda expression must reference a settable and gettable property.");
var vector = (Vector)getMethod.Invoke(obj, null);
vector.x += x;
setMethod.Invoke(obj, new object[]{vector});
}
else
{
throw new ArgumentException("lambda expression must reference an accessible property.");
}
}
and then you can use the extension method like this
var line = new Line();
line.MoveX(l => l.start, 2);
Related Topics
Evaluating String "3*(4+2)" Yield Int 18
What Is the Best Workaround For the Wcf Client 'Using' Block Issue
How to Provide User Name and Password When Connecting to a Network Share
How to Post Messages to an Sta Thread Running a Message Pump
How to Convert Utf-8 Byte[] to String
What's the Fastest Way to Read a Text File Line-By-Line
Why Is the Console Window Closing Immediately Once Displayed My Output
Can't Operator == Be Applied to Generic Types in C#
In C#, Should I Use String.Empty or String.Empty or "" to Intitialize a String
How to Await an Event Instead of Another Async Method
Listing All Permutations of a String/Integer
In C#, Difference Between Public, Private, Protected, and Having No Access Modifier
What Are Good Ways to Prevent SQL Injection