Is there a way to determine whether a parameter has this modifier? - c#

I would like to determine if a parameter has this modifier using Reflection.I have looked at properties of ParameterInfo class, but couldn't find anything useful.I know the extension methods are just syntactic sugars but I believe there should be a way to determine whether a method is an extension method.
The only thing that distinguishes extension methods from other static methods (that are defined in a static, public class) is this modifier.
For example this is not an extension method:
public static int Square(int x) { return x * x; }
But this is:
public static int Square(this int x) { return x * x; }
So how can I distinguish between two methods using Reflection or something else if possible?

It's not exactly the same, but you can check whether the method has the ExtensionAttribute applied to it.
var method = type.GetMethod("Square");
if (method.IsDefined(typeof(ExtensionAttribute), false))
{
// Yup, it's an extension method
}
Now I say it's not exactly the same, because you could have written:
[Extension]
public static int Square(int x) { return x * x; }
... and the compiler would still pick it up as an extension method. So this does detect whether it's an extension method (assuming it's in a static top-level non-generic type) but it doesn't detect for certain whether the source code had the this modifier on the first parameter.

Related

Is it possible to change the parameters that a predefined method can take in C#?

Im not sure if this is possible. Im using a method that takes the parameter int but i found myself in a situation where i need to be able to use a float value. Does anyone know if there is anyway to change the parameters that a predefined method can take?
Thanks All
Best
Alex
You can overload a method as follows:
public static float myMethod(float sumNumber)
{
// whatever you need for code here
return sumNumber;
}
public static int myMethod(int sumNumber)
{
// whatever you need for code here
return sumNumber;
}
C# has generics for his type of requirement, where you want to apply a logic indifferent of the type of parameter input
for example :
T foo<T>(T param)
{
return param + 1;
}
//and it can be used like this
int i;
foo<int>(i); // return type is int
float f;
foo<float>(f); // return type is float
Member overloading means creating two or more members on the same type that differ only in the number or type of parameters but have the same name. - Microsoft MSDN
// your method
public static double Inc(int i)
{
return i + 1;
}
// your method (overloaded)
public static double Inc(double d)
{
return d + 1;
}
int i = Inc(3);
double d = Inc(2.0); // You can use the same method with different parameter types
The website www.dotnetperls.com has a lot of nice examples. If you want to see another explanation besides MSDN, you may read this.
You can define a generic class for such methods.
public class GenericMethodsClass<T>
{
public static T myMethod(T sumNumber)
{
// whatever you need for code here
return sumNumber;
}
}
Calling:
GenericMethodsClass<int>.myMethod(1);
GenericMethodsClass<double>.myMethod(1.2);

Are all methods in a delegate treated equally or are some of them special?

I recently learned that a delegate is not a pointer to ONE function, but to a LIST of functions (called "invocation list"). I would like to know if there is any difference between the methods in the list: Is one of them, or are several of them, somehow special? Are some of them stored somewhere else than in the invocation list?
I ask because I found a property Delegate.Method in the MSDN documentation (https://msdn.microsoft.com/en-us/library/system.delegate.method(v=vs.110).aspx) where it says
Delegate.Method Property:
Gets the method represented by the delegate.
Assuming that all methods stored in the delegate are treated equally, it is not clear to me WHICH method they mean. Most probably they mean the first one, but this is just a guess. Anyone out there who knows?
Just tested it:
public class Program
{
public delegate int Operation(int x, int y);
public static int Add(int x, int y)
{
return x+y;
}
public static int Sub(int x, int y)
{
return x-y;
}
public static void Main()
{
Operation o = new Operation(Add);
o += Sub;
Console.WriteLine(o.Method);
}
}
And the output is the last assigned method:
Int32 Sub(Int32, Int32)
Even though Method property will return the last method it does not treat it differently and it is not speical over other other methods(except the fact that this is the last method that was added to the delagate and according to #Dennies_E commenet if the delegate return any value it will be the last method return value, in this case Sub method return value).
If you want to see all the assigend methods you can use Delegate.GetInvocationList method:
foreach(Opeartion operation in o.GetInvocationList())
{
Console.WriteLine(operation.Method);
}
This will print all the methods in the order they were added:
Int32 Add(Int32, Int32)
Int32 Sub(Int32, Int32)

Roslyn: Determine if ITypeParameterSymbols are equivalent

I'm trying to determine with Roslyn if two method signatures are equivalent (ignoring parameter order). It becomes somewhat non-trivial when the methods contain generic parameters.
I would like to detect AGenericMethod and AnotherGenericMethod below as having equivalent signatures:
public void AGenericMethod<X>(X someX, int someInt) where X : IEnumerable<int>
{
//...
}
public void AnotherGenericMethod<Y>(Y someY, int someInt) where Y : IEnumerable<int>
{
//...
}
It seems like .Equals() will return false for the ITypeParameterSymbols corresponding to X and Y.
Is there any existing functionality in Roslyn for classing ITypeParameterSymbols as 'equivalent' (in the sense of having equivalent constraints)? If not, what would be the best way to implement this (considering that the constraints may themselves be type parameters)?

How does C# resolve different extension method overloads?

I've got a code snippet as below:
public static class M
{
public static int Plus(this int i, int p=6)
{
return i + p;
}
}
public static class N
{
public static int Plus(this int i)
{
return i + 10;
}
}
class Program
{
static void Main()
{
int i = 3.Plus();
Console.WriteLine(i);
}
}
Run the program, it outputs "13", which indicates class N's extension method is called. Why class M's method is not matched?
Then if I remove class N, OK, class M's extension method is called, it outputs "9" as expected.
So my question is, is there a rule in C# or .net framework to determine, which extension method is to be called if multiple matches are there? Is this related to overload resolution rule or something else?
Thanks very much.
The same overloading rules apply to extension methods as for all other methods. N is used because it is a better match. M may have an optional parameter, but the no parameter option is a better fit as the rules favour the option with the fewest parameters.
From Named and Optional Arguments (C# Programming Guide):
If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.
However, "closeness" comes into play with extension methods too, as described in Eric Lippert's blog:
The consequence of this is that if you restructure your code to:
namespace X
{
public static class N
{
public static int Plus(this int i)
{
return i + 10;
}
}
}
namespace ConsoleApplication1
{
public static class M
{
public static int Plus(this int i, int p = 6)
{
return i + p;
}
}
internal class Program
{
private static void Main()
{
int i = 3.Plus();
Console.WriteLine(i);
}
}
}
Then the number displayed is 9. In other words, the version with an optional parameter is chosen as it's in the same namespace and thus "closer".
This has nothing to do with extension methods specifically. At the tie breaking phase of the overload resolution algorithm, a method that matches the call without application of default arguments is preferred over a method that requires application of said default arguments to match the call.
As the C# specification puts it, at page 154:
[...] if all parameters of MP have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in MQ then MP is better than MQ.

C# operators as functions

Is there a way to use operators as functions without declaring them manually?
Func<bool, bool> not = x => !x;
Similar to (+)/(-) in Haskell. Would be handy in various LINQ scenarios involving conditional query construction. Maybe some C# (4.0+) trick I don't know about.
Edit: here is a sample to clarify what I mean:
int MyWhere(Func<bool, bool, bool> cond) {}
a usual call would be:
MyWhere((x,y) => x && y)
a cool call would be (assuming Haskell style):
MyWhere((&&))
No.
You can find the definitions (F12 in VS) for the operators you can overload, and there exists a
// struct Double
public static bool operator ==(double left, double right);
But there is no way to call Double.operator==(a, b).
The Framework does offer a a.Equals(b) for this particualr case, but there is no a.Add(b).
For documentary purposes: user-defined operator are functions, however the C# language explicitly prohibits explicit calls (don't know the rationale). E.g.:
public class X
{
public static X operator+(X a, X b)
{
return new X();
}
}
public class Program
{
public static void Main(string[] args)
{
var q = new X() + new X();
X.op_Addition(q,q); // error CS0571:
// `Program.X.operator +(Program.X, Program.X)': cannot explicitly
// call operator or accessor
}
}
If you were writing IL, you'd write this:
newobj instance void class X::'.ctor'()
newobj instance void class X::'.ctor'()
call class X class X::op_Addition(class X, class X)
stloc.0
If i understand what you are want to do right, you can use System.Reflection and Delegate.CreateDelegate to create a delegate to the operator method.
Of course i never testet it, but operator methods are methods so it should work.
This could also be automated ( To save time compared to the straight forward method ).
See:
http://msdn.microsoft.com/de-de/library/53cz7sc6.aspx

Categories