Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a C# Property ever have no GetMethod and no SetMethod

Browsing the .NET core source code for System.Linq.Expressions, I found the following code located here:

MethodInfo mi = property.GetGetMethod(true);
if (mi == null)
{
    mi = property.GetSetMethod(true);
    if (mi == null)
    {
        throw Error.PropertyDoesNotHaveAccessor(property, nameof(property));
    }
}

Is there any way that GetGetMethod and GetSetMethod can both return null, as seems to be accounted for here? Is this dead code? The C# compiler doesn't allow for a property to have no getter and no setter, so how is this possible for PropertyInfo.

My motivation is to contribute to the OSS code by adding test coverage, so I'm trying to see what test cases would cover this

like image 200
H Bellamy Avatar asked Aug 17 '16 21:08

H Bellamy


People also ask

How many cans of AC Pro do I need?

Most cars hold between 28 and 32 ounces of refrigerant (or about 2—3 12oz cans), however larger vehicles and those with rear A/C will likely hold more. Check your vehicle manual for the system capacity for your specific vehicle.

Why won't my AC system take a charge?

It's possible that an internal component is broken. You will have to fix the compressor before you can recharge the Freon. If you see a very high pressure on the high side gauge and very low pressure on the low side gauge, there's a Freon blockage.

How much does it cost to recharge AC?

Most homeowners will pay in the range of $200 to $400 for a refill, depending on the type and size of their HVAC unit. If you own a larger r22 unit, you may have to spend $600 or more.

Will AutoZone put Freon in my car?

If you need help performing this, or any AC recharge or service, check out our list of preferred shops in your area that can help. Or, if you'd like to tackle the job yourself, AutoZone has all the tools and refrigerant to service your R-134A or R-12 vehicle.


3 Answers

You can create a property with no accessors in IL:

.class public C
{
  .property int32 Count() { } 
}

Which can then trigger the code path you mentioned:

var prop = typeof(C).GetProperty("Count", BindingFlags.NonPublic | BindingFlags.Instance);

Expression.Property(null, prop);

This code throws:

ArgumentException: The property 'Int32 Count' has no 'get' or 'set' accessors

like image 81
svick Avatar answered Oct 18 '22 20:10

svick


According to the CLI Specification,

CLS Rule 28: Properties shall adhere to a specific naming pattern. See §I.10.4. The SpecialName attribute referred to in CLS rule 24 shall be ignored in appropriate name comparisons and shall adhere to identifier rules. A property shall have a getter method, a setter method, or both.

That's on page 52 of the linked PDF.

That seems to say that one or the other must be there.

It appears that the developer decided to interpret the specification that way, and acted accordingly in the face of invalid data. Seems like quite a reasonable thing to do.

It might be possible, by writing IL or by editing the metadata afterwards, to create a property that has no getter or setter. And the .NET loader might go ahead and load it anyway, even if it is considered an invalid property. I've seen that kind of thing happen in other fields.

With that in mind, code that handles the "impossible" situation of a property with neither getter nor setter doesn't seem like dead code to me.

like image 39
Jim Mischel Avatar answered Oct 18 '22 22:10

Jim Mischel


After some research, there is a way to achieve this, via System.Reflection.Emit

AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Name"), AssemblyBuilderAccess.Run);
ModuleBuilder module = assembly.DefineDynamicModule("Module");

TypeBuilder type = module.DefineType("Type");
PropertyBuilder property = type.DefineProperty("Property", PropertyAttributes.None, typeof(void), new Type[0]);

Type createdType = type.CreateType();
PropertyInfo createdProperty = createdType.GetTypeInfo().DeclaredProperties.First();

Console.WriteLine(createdProperty.GetGetMethod(true) == null);
Console.WriteLine(createdProperty.GetSetMethod(true) == null);

This is obviously a strange way to have no setter or getter without IL

like image 2
H Bellamy Avatar answered Oct 18 '22 22:10

H Bellamy