Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differentiating Between OutAttribute and out Modifier in Reflection

Tags:

c#

reflection

If I write this:

public interface IOutModifier
{
    void OutModifier(out int a);
}

And try to implement it in an interface, VS generates this (as expected):

public class IOM : IOutModifier
{
    public void OutModifier(out int a)
    {
        throw new NotImplementedException();
    }
}

If I write this:

public interface IOutAndOutAttributeModifier
{
    void OutAndOutAttributeModifier([Out] out int a);
}

VS will implement it like this:

public class IOOAM : IOutAndOutAttributeModifier
{
    public void OutAndOutAttributeModifier([Out]out int a)
    {
        throw new NotImplementedException();
    }
}

Side note: writing this:

public interface IOutAttributeModifier
{
    void OutAttributeModifier([Out] int a);
}

will be implemented like this:

public class IOAM : IOutAttributeModifier
{
    public void OutAttributeModifier([Out] int a)
    {
        throw new NotImplementedException();
    }
}

So, there seems to be a way to differentiate between the OutAttribute being present or not...but I can't figure out how (via Reflection). In both cases any of the methods to get custom attribute information (GetCustomAttributes(), GetCustomAttributeData(), etc.) report that the OutAttribute exists on all interface methods. This isn't a case either with code existing in the current project - if I reference an assembly with these interfaces, VS still generates the same code shown above.

So, how can I tell the difference between a parameter that is just "out" and one that had the "[Out]" attribute added to it explicitly?

like image 738
JasonBock Avatar asked Nov 26 '25 16:11

JasonBock


1 Answers

Actually both of your code isn't same.

IOM is the proper use of output parameter. IOAM is just a fail.

For example try calling the method with value as opposed to the variable. It should fail to compile. Because out argument passed to the parameter must be a variable not a value.

IOM iom = new IOM();
iom.OutModifier(4);//Fails as expected

IOAM ioam = new IOAM();
ioam.OutAttributeModifier(4);//Compiles fine

This is because out parameter must be passed by reference. In your example IOAM you pass it by value.

MSIL code for IOM is

.method public hidebysig newslot virtual final instance void OutModifier([out] int32& a) cil managed

MSIL code for IAOM is

.method public hidebysig newslot virtual final instance void OutAttributeModifier([out] int32 a) cil managed

Note in IAOM.OutAttributeModifier a parameter isn't passed by reference.

I think this is an oversight in your case. If this is intentional, then you can differentiate it by checking whether the parameter is passed by ref or not. You do it by calling ParameterInfo.ParameterType.IsByRef.

like image 95
Sriram Sakthivel Avatar answered Nov 29 '25 04:11

Sriram Sakthivel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!