vendredi 1 décembre 2017

VerificationException when setting readonly fields (C#)

I am trying to write code that can set arbitrary fields on caller-provided objects which may include anonymous ones. Creating delegates is not possible (Expression compiler realizes that anonymous objects' fields are readonly), so I chose to emit some IL. However, when doing this I am running into VerificationException ("Operation could destabilize he runtime"). The same simple code runs just fine on objects with regular fields. Fails on readonly fields. What else could be done here? I am running .Net 4.6.2.

Thanks in advance!

class TestRegular
{
    private string field;
}

class TestReadOnly
{
    private readonly string field;
}

class Program
{
    static void Main(string[] args)
    {
        Verify(new TestRegular());     // this works
        Verify(new TestReadOnly());    // this does not work
        Verify(new { field = "abc" }); // this does not work
        Console.WriteLine("Done");
    }

    private static void Verify<T>(T test)
    {
        var fields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
        Action <T, object> setter = CompileSetter<T>(fields[0]);
        setter(test, "value");
    }

    private static Action<TResult, object> CompileSetter<TResult>(FieldInfo field)
    {
        string methodName = field.ReflectedType.FullName + ".TestSetter";
        DynamicMethod setterMethod = new DynamicMethod(methodName, null, new[] { typeof(TResult), typeof(object) }, true);
        ILGenerator gen = setterMethod.GetILGenerator();

        gen.Emit(OpCodes.Ldarg_0);
        gen.Emit(OpCodes.Ldarg_1);
        gen.Emit(OpCodes.Castclass, field.FieldType);
        gen.Emit(OpCodes.Stfld, field);

        gen.Emit(OpCodes.Ret);
        return (Action<TResult, object>)setterMethod.CreateDelegate(typeof(Action<TResult, object>));
    }
}





Check if function belongs to a class

I'm trying to write a documentation testing tool which checks whether the docstrings match the actual function signature (among other things). However, I've run into a bit of a roadblock. I can't find a way to figure out whether a given function belongs to a class or not.

import inspect

def func1():
    pass


class Foo:
    def method(self):
        pass

print(inspect.ismethod(func1))  # prints False
print(inspect.ismethod(Foo().method)) # prints True
print(inspect.ismethod(Foo.method)) # prints False - I want something that prints True here

The problem is that methods usually have self as their first parameter, and this is never documented (for obvious reasons). This would cause my tests to fail, since they'd encounter a parameter that's not documented.

I would prefer to not explicitly check if the first parameter is called self and skip it, because a) nothing prevents a function from having a parameter called self and b) the name self itself is a matter of convention (so you could have a method with a first param that's called this_is_definitely_not_self) and my tool would fail in either case. I also can't just initialize an object and check if the function is a method, because this would fail with any class that takes required parameters in its __init__.

So the question is, is there any way I can detect if a function is a method before it is actually bound to an object? Or do I need to resign myself to just checking if the first parameter is called self?





Determine assembly framework without loading it

I'm writing a C# console application which must run under .NET Framework 2.0, but needs to be able to identify an assembly's framework version, even if it's higher than .NET 2.0.

I can't use AssemblyName.GetAssemblyName or related functions because they will throw a BadImageFormatException if the target assembly was built under a later framework version. Is there some way to get this information without attempting to load the assembly in any way?

Note: I know that this is possible using PowerShell, but that tool is not available in the target environment.





Get WebView implementation programmatically

It is of course possible for a user to choose which WebView implementation to use, as explained here. Is it possible to determine programatically which implementation they have chosen? I know that it's possible to get the User-Agent string programatically, but that's not quite the same information.

enter image description here

enter image description here

In the above example, I want to know that "Chrome Stable" has been selected as the WebView implementation. On some user devices, there is apparently also an option to choose "Android System WebView" from the list, even though Chrome is also an option, and even though the Android System WebView is disabled in the system apps listing.

This is troubling because presumably the Android System WebView will be receiving no further updates (it will be stuck in the past), while Chrome will be receiving updates and is the more appropriate choice as the WebView implementation. It is even more troubling because the selection of WebView implementation is completely hidden from the ordinary user.

So I want to know particularly if "Android System WebView" is selected, even for Android 7.0+ where it would seem more appropriate that Chrome is selected instead.





How to check AnnotationInvocationHandler relationship with Annotation

I have an annotation defined as

@interface A {}

A class using this annotation

class C {
  @A String f;
}

However, at runtime it is wrapped by a Proxy with AnnotationInvocationHandler, e.g. Field f = C.class.getField("f"); f.getDeclaredAnnotations() returns an array of this Proxy. How can I check wether field f of class C is annotated with annotation A in this situation?

Note: f.isAnnotationPresent(A.class) returns false





C# OrderBy IQueryable

Is it possible to in C# to OrderBy IQueryable with Reflection to get Property name for ordering by property attribute for example Attribute Name = "Key"?





Reflection + AOP - advice not intercepted when calling method via invoke

Via Reflection:

Class c = Class.forName("mypackage.DiodeService");
Method m = c.getDeclaredMethod("blink");
Object t = c.newInstance();
Object o = m.invoke(t);

Method from DiodeService is invoked:

@ValueGreaterThan
public void blink(){
    log.info("Diode service: blink()");
}

On the annotation @ValueGreaterThan is listening aspect:

@Around(value = "mypackage.CommonJoinPointConfig.valueGreaterThanAspect())") public void around(ProceedingJoinPoint joinPoint) throws Throwable {
    log.info("Value greater than aspect {}", joinPoint); }

BUT: The around advice is never intercepted, when calling method by "invoke".

Around advice is intercepted normally, when calling by diodeService.blink()

Please, any ideas?