dimanche 31 janvier 2021

Returning an anonymous type from lamda/ Code explanation

This code comes from mr.Lukazoid member of stackoverflow. I would like to know how this works. is a bit strange for me how you call a method like this. What is the role of 'TResult'!

public static string[] Foo<T, TResult>(Expression<Func<T, TResult>> func)
{
    return typeof(TResult).GetProperties().Select(pi => pi.Name).ToArray();
}

Foo((Person x) => new { x.LastName, x.DateOfBirth });

Thanks a lot.





how to modify the index of a private static final array that is in another class

Ive been trying everything online and have yet to find it. Heres my code. Please tell me what to fix Im so confused.

private void loadProtectionEnchant() {
    
    int protectionID = 0;
    
    try {
        Field id = net.minecraft.server.v1_8_R3.Enchantment.class.getDeclaredField("byId");
        Field protEnchant = Enchantment.class.getDeclaredField("PROTECTION_ENVIRONMENTAL");
        
        id.setAccessible(true);
        protEnchant.setAccessible(true);
        
         Object[] byID = (Object[]) id.get(null);
        byID[protectionID] = null;
        
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(id, id.getModifiers() & ~Modifier.FINAL & ~Modifier.PRIVATE);
        id.setAccessible(true);
        System.out.println(byID.toString());
        
        System.out.println(id.toString());
        
        id.set(null, byID);
        protEnchant.set(null, new CustomProtectionEnchantment(protectionID, new MinecraftKey("protection"), 10, 0));
        
    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
        e.printStackTrace();
    }
    
    System.out.println(Enchantment.PROTECTION_ENVIRONMENTAL.toString());
    
}

and heres my error java.lang.IllegalAccessException: Can not set static final [Lnet.minecraft.server.v1_8_R3.Enchantment; field net.minecraft.server.v1_8_R3.Enchantment.byId to [Lnet.minecraft.server.v1_8_R3.Enchantment;

Please tell me if u know whats wrong TY.





Gluon Reflection list external jnativehook file GlobalScreen ( I have issue )

I'm Still learning about gluon How it's works I'm a student. now the problem is it's not running after the client:build before it's working perfectly.

so here is the problem. I have added GlobalScreen class in reflection but it's a method or something I don't understand giving me an issue so how to solve it please guide me.

      [Sun Jan 31 22:19:45 PKT 2021][INFO] ==================== RUN TASK ====================
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB] Hello There
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB] GG1
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB] GG2
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB] Jan 31, 2021 10:19:46 PM org.jnativehook.DefaultLibraryLocator getLibraries
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB] SEVERE: Unable to extract the native library /org/jnativehook/lib/windows/x86_64/JNativeHook.dll!
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB] Exception in Application start method
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB] Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at java.lang.Thread.run(Thread.java:834)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:519)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.oracle.svm.core.windows.WindowsJavaThreads.osThreadStartRoutine(WindowsJavaThreads.java:138)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB] Caused by: java.lang.UnsatisfiedLinkError: org.jnativehook.GlobalScreen.getAutoRepeatRate()Ljava/lang/Integer; [symbol: Java_org_jnativehook_GlobalScreen_getAutoRepeatRate or Java_org_jnativehook_GlobalScreen_getAutoRepeatRate__]
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.oracle.svm.jni.access.JNINativeLinkage.getOrFindEntryPoint(JNINativeLinkage.java:153)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.oracle.svm.jni.JNIGeneratedMethodSupport.nativeCallAddress(JNIGeneratedMethodSupport.java:57)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at org.jnativehook.GlobalScreen.getAutoRepeatRate(Unknown Source)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at org.jnativehook.GlobalScreen.<clinit>(Unknown Source)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:351)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:271)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at sample.Main.start(Main.java:34)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at java.security.AccessController.doPrivileged(AccessController.java:102)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_VA_LIST:Ljava_lang_Runnable_2_0002erun_00028_00029V(JNIJavaCallWrappers.java:0)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.glass.ui.win.WinApplication._runLoop(WinApplication.java)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    [Sun Jan 31 22:19:46 PKT 2021][INFO] [SUB]      ... 3 more
                 _______  ___      __   __  _______  __    _
                |       ||   |    |  | |  ||       ||  |  | |
                |    ___||   |    |  | |  ||   _   ||   |_| |
                |   | __ |   |    |  |_|  ||  | |  ||       |
                |   ||  ||   |___ |       ||  |_|  ||  _    |
                |   |_| ||       ||       ||       || | |   |
                |_______||_______||_______||_______||_|  |__|
    
        Access to the latest docs, tips and tricks and more info on
        how to get support? Register your usage of Gluon Substrate now at
    
        https://gluonhq.com/activate
    
    
    
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  6.452 s
    [INFO] Finished at: 2021-01-31T22:19:49+05:00
    [INFO] ------------------------------------------------------------------------

this is my pom file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>GameCheats</groupId>
    <artifactId>InvokerBotKey</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>
    <name>InvokerBotKeys</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <mainClassName>sample.Launcher</mainClassName>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>15.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>15.0.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.1stleg/jnativehook -->
        <dependency>
            <groupId>com.1stleg</groupId>
            <artifactId>jnativehook</artifactId>
            <version>2.1.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.5</version>
                <configuration>
                    <mainClass>${mainClassName}</mainClass>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.gluonhq</groupId>
                <artifactId>client-maven-plugin</artifactId>
                <version>0.1.35</version>
                <configuration>
                    <target>${client.target}</target>
                    <mainClass>${mainClassName}</mainClass>
                    <reflectionList>
                        <list>sample.Controller</list>
                        <list>sample.Main</list>
                        <list>sample.HotKeys</list>
                        <list>sample.Invoker</list>
                        <list>sample.GlobalKeyListener</list>
                        <list>javafx.application.Application</list>
                        <list>javafx.scene.Parent</list>
                        <list>javafx.scene.Scene</list>
                        <list>javafx.scene.robot.Robot</list>
                        <list>javafx.stage.Stage</list>
                        <list>javafx.fxml.FXMLLoader</list>
                        <list>javafx.scene.input.KeyCode</list>
                        <list>java.util.concurrent.TimeUnit</list>
                        <list>javafx.event.ActionEvent</list>
                        <list>javafx.fxml.FXML</list>
                        <list>javafx.scene.control.TextField</list>
                        <list>javafx.scene.control.ToggleButton</list>
                        <list>javafx.application.Platform</list>
                        <list>org.jnativehook.GlobalScreen</list>
                        <list>org.jnativehook.NativeHookException</list>
                        <list>org.jnativehook.keyboard.NativeKeyEvent</list>
                        <list>org.jnativehook.keyboard.NativeKeyListener</list>
                        <list>org.jnativehook.DefaultLibraryLocator</list>
                    </reflectionList>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <profiles>
        <profile>
            <id>desktop</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <client.target>host</client.target>
            </properties>
        </profile>
    </profiles>
    <pluginRepositories>
        <pluginRepository>
            <id>gluon-releases</id>
            <url>
                http://nexus.gluonhq.com/nexus/content/repositories/releases
            </url>
        </pluginRepository>
    </pluginRepositories>
</project>




Can I get a generic template from string to input to a generic Method?

private void Message<T>(byte[] body) where T : someClass
{
    ...
}

I have this method, and I don't use the instance of T, I only need "T" which I can put that into another generic class. Also I have this switch statement :

                case SCPacket.Move:
                    Message<Corps.Move>(task.body);
                    break;
                case SCPacket.Push:
                    Pushed(task.body);
                    break;
                case SCPacket.ShortChat:
                    Message<Corps.ShortChat>(task.body);
                    break;
                case SCPacket.MediumChat:
                    Message<Corps.MediumChat>(task.body);
                    break;
                case SCPacket.LongChat:
                    Message<Corps.LongChat>(task.body);
                    break;

Actually What I'm trying to do is just kind of refactoring.

I guess I can get a "T" which I can put that into Message from enum(like above, I matched between element of enum and nested class's name.

I tried to use Type.GetType(), but in this case It returns variable that I cannot use in the generic template.

If do you have any idea coming up with, please let me know.





samedi 30 janvier 2021

Should I be worried about the caveats of using unsafe?

The Go unsafe module comes with caveats that I am not sure whether should concern me.

One particular note that I don't really understand is:

Packages that import unsafe may be non-portable..

  • If my package is doing what I want it to do should I be worried by it being non-portable?
  • How does Go code become non-portable?
  • And what are the other key 'got yas' I should be looking out for when using this package?

The Project (for those interested - https://github.com/littlecluster/struct_dot_notation)

I've started a small project to allow me to update structs using dot notation, for what I want to do it is working and my needs don't really get very complex. I'm basically splitting a string, reflecting on a struct and iterating through the fields until I find the field I want to update and then updating it.





vendredi 29 janvier 2021

What is the difference between using MaxLengthAttribute and a validation in the setter of the property? [closed]

Which is the difference between using an attribute like

[MaxLength(15)]
public string name{get;set;}

to validate this property and putting a validation code in the setter of the property.

public string name{get;
  set{
    if(value.Length > 15){throw new error... } };
}

Why we should use reflection and attributes when we can validate the property in the setter and its easier than using reflection and an attribute, on run time we instantiate the class, we wait for the value input from the user and if the value will not be valid will not be stored.

So why we should use an attribute in this case and no validation in the setter which is easier?





C# Reflection -Missing Fields?

I'm using reflection to create a new instance Item B from an instance of Item A. These are different objects, but share some level of commonality. In this sample case, they both inherit from a base class.

Base Class:

public abstract class Common
{
    public string Value { get; set; }
    public virtual string Ignored { get; }
}

I then have two classes that I am working with, the original class, and the output:

public class Original : Common
{
    public override string Ignored => "This will get ignored";
}

public class Output : Common { }

If I create a new instance of Original and give the Value Property a value, the I am able to see that value within one of the auto-generated backing fields. All of this using reflection, I can then use the Activator to create an instance of my Output class and am able to set the value of the Value Property

My process is to find the commonality, get all fields (properties if based on an interface) of that object, and then with the FieldInfo I can read the value from Original and set it in Output.

My problem lies with the virtual property called Ignored, the backing field doesn't have a value, but if I read directly from the propertyinfo then I can get the value.

What am I missing with my understanding of how this following line is made up?

public override string Ignored => "This will get ignored";

Is it because it is an override? Or because it uses the => way of setting the property.

If this doesn't have an underlying field, what is the best way to match already used properties so that I only find those that don't have a backing field?

This is just test code at the moment, but for reference, this is basically my method:

private object CreateObject(object original, Type commonType, Type outputType)
{
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

    var response = Activator.CreateInstance(outputType, nonPublic: true);
    if (commonType.IsInterface)
    {
        foreach (var info in commonType.GetProperties(flags))
        {
            object clonedValue = info.GetValue(original); //this is simplified for ease
            var method = outputType.GetProperty(info.Name)?.GetSetMethod(nonPublic: true);
            if (method != null)
                method.Invoke(response, flags, null, new object[] { clonedValue }, null);
        }
    }
    else
    {
        // ** This only gets the fields of the common type **
        //foreach (var info in commonType.GetFields(flags))
        //{
        //    object clonedValue = this.Clone(info.GetValue(original), implementations);
        //    info.SetValue(response, clonedValue);
        //}

        // ** Testing to get all fields of original type, and then its base type - based on the above commented out code
        var fields = this.GetFieldsRecursive(original.GetType(), flags);
        //var value = commonType.GetProperty("Ignored").GetValue(original); // Proves I can get the value from the original object
        foreach (var info in fields)
        {
            object clonedValue = info.GetValue(original); // this is simplified for ease
            info.SetValue(response, clonedValue);
        }
    }


    return response;
}

I hope that makes sense

Any ability to help fill some gaps in my knowledge would be massively appreciated.





Variable generic type count runtime reflection

Right now I have this code:

//some Method detection here..

var methodParams = method.GetParameters();
Type actionType = null;

switch(methodParams.Length)
{
    case 1:
        actionType = typeof(Action<>);
        break;

    case 2:
        actionType = typeof(Action<,>);
        break;

    case 3:
        actionType = typeof(Action<,,>);
        break;

    case 4:
        actionType = typeof(Action<,,,>);
        break;

    case 5:
        actionType = typeof(Action<,,,,>);
        break;
}

var actionGenericType = actionType.MakeGenericType(methodParams.Select(x => x.ParameterType).ToArray());

I don't like this switch statement but I haven't yet found a way to select the Action generic overload based on the number of parameters (or based on any runtime int).

Is there a more elegant way / oneliner to do something like this?

I don't want to use a dispatch table.





jeudi 28 janvier 2021

Converting String to Generics type argument in Java

I would like to write a Generic program that receives a String from the user and creates a container of that type using reflection. This should be something on the lines of

public static void main(String []args) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Enter the type you want to use ");
    String typeName = scanner.nextLine();
    Set<????> mySet = new HashSet(); 
}

What should I put in the ???? part? Is this possible?





Java superinterfaces runtime difference Java 8 vs Java 9

I noticed a difference in the output of the following program when run with Java 8 and Java 9.

import java.lang.reflect.Method;
public class OrderingTest {
    public static void main(String[] args) {
        ServiceImpl service = new ServiceImpl();
        for (Method method : service.getClass().getMethods()) {
            for (Class<?> anInterface : method.getDeclaringClass().getInterfaces()) {
                try {
                    Method intfMethod = anInterface.getMethod(method.getName(), method.getParameterTypes());
                    System.out.println("intfMethod = " + intfMethod);
                } catch (NoSuchMethodException e) { }
            }
        }
    }
}

class ServiceImpl implements ServiceX {
    @Override
    public Foo getType() { return null; }
}

interface ServiceX extends ServiceA<Foo>, ServiceB { }
abstract class Goo { }
class Foo extends Goo { }

interface ServiceA<S> {
    S getType();
}
interface ServiceB {
    @java.lang.Deprecated
    Goo getType();
}

You can run both versions of java here: https://www.jdoodle.com/online-java-compiler/

Java 8 outputs:

intfMethod = public abstract java.lang.Object ServiceA.getType()
intfMethod = public abstract java.lang.Object ServiceA.getType()
intfMethod = public abstract java.lang.Object ServiceA.getType()

Java 9 outputs:

intfMethod = public abstract Goo ServiceB.getType()
intfMethod = public abstract Goo ServiceB.getType()
intfMethod = public abstract Goo ServiceB.getType()

But when I reorder the super-interfaces to:

interface ServiceX extends ServiceB, ServiceA<Foo> { }

Then both versions of java output:

intfMethod = public abstract Goo ServiceB.getType()
intfMethod = public abstract Goo ServiceB.getType()
intfMethod = public abstract Goo ServiceB.getType()

I was wondering what is causing it? Is there a new java feature I am not aware of?

Java 8 documentation https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8

Java 9 documentation https://docs.oracle.com/javase/specs/jls/se9/html/jls-8.html#jls-8.4.8





How to get annotation used on inner generic type?

My question is somewhat a little more advanced reflection problem.

Suppose you have a class:

import java.util.List;

public class Sample
{

    private List<@First List<@Second String>> field;

}

As you see, type of field is List<List<String>>. Assume you have 2 different annotations: @First and @Second. These annotations are put on this field's generic type, respectively. Now, my goal is to access these both annotations at runtime.

Here is my code:

Field field = Sample.class.getDeclaredField("field");
AnnotatedType annotatedType = field.getAnnotatedType();
AnnotatedParameterizedType annotatedParameterizedType = (AnnotatedParameterizedType) annotatedType;

When I invoke getAnnotatedType() on field, it returns me an AnnotatedParameterizedType.

AnnotatedType annotatedActualTypeArgument = annotatedParameterizedType.getAnnotatedActualTypeArguments()[0];
Annotation firstAnnotation = annotatedActualTypeArgument.getAnnotations()[0];

getAnnotatedActualTypeArguments() method actually gives me the @First annnotation.

ParameterizedType innerType = (ParameterizedType) annotatedActualTypeArgument.getType();

However, when I try to get type of the inner generic argument, it gives me a ParameterizedType. Which correctly defines the type of inner-most argument: List<String>. But, because it is not of type AnnotatedParameterizedType, I cannot access @Second annotation.

Is there any way I can access the second annotation as well at runtime?





Generate an instantiable class based on a static class reflectively

Can I (using reflection I presume?) create a class with all the same method names as java.lang.Math and each method just forwards it to Math?

E.g.

public class MyMath {
  public MyMath() {}

  public double abs(double a) {
    return Math.abs(a);
  }

  public float abs(float a) {
    return Math.abs(a);
  }

  public int abs(int a) {
    return Math.abs(a);
  }

  ...

  public double acos(double a) {
    return Math.acos(a);
  }
  
  ...

How could I generate this programmatically?





mercredi 27 janvier 2021

Fody and Assembly.GetExecutingAssembly().Location returns empty string

I was calling Assembly.GetExecutingAssembly().Location in one of the dlls of a solution of mine. When I tried to use Fody (https://www.nuget.org/packages/Fody/) to package my binaries into a single binary, I noticed that this call started returning the empty string instead of the location of the executing assembly. Should this be considered a bug? And is there a way to get this information when using Fody? It seems to work fine if I make the call from the main project of my solution.

This is my main method:

static void Main(string[] args)
{
    Console.WriteLine($"From Main: \"{Assembly.GetExecutingAssembly().Location}\"");
    Console.WriteLine($"From dll:  \"{Class1.GetLocation()}\"");
}

And then the GetLocation method is defined in a dll like this:

public static string GetLocation()
{
    return Assembly.GetExecutingAssembly().Location;
}

The output in the console without Fody looks like this:

From Main: "C:\Prog\ConsoleApp1\bin\Debug\ConsoleApp1.exe"
From dll:  "C:\Prog\ConsoleApp1\bin\Debug\ClassLibrary1.dll"

While after adding Fody, it looks like this:

From Main: "C:\Prog\ConsoleApp1\bin\Debug\ConsoleApp1.exe"
From dll:  ""




Reflection matrix for an arbitrary plane

I have seen the HouseHolder equation which creates an matrix that reflects an point about an plane but the equation assumes the plane only has a normal vector v.

My plane has 3 components

The normal unit vector              V
A point that lies on the plane      P
Distance of the plane from origin   D

All stored in seperate variables.

How would I extend the equation to take the point and distance into its calculation or do I need a different approach?





Simple JSON deserialization of records incorrect (Delphi Sydney [10.4])

What happened to the JSON deserializer of Delphi Sydney (10.4)? After the migration from Delphi Seattle to Sydney the standard marshal has problems with the deserialization of simple records.

Here is an example and simplified representation of my problem:

Data structure - Interation 1:

TAnalysisAdditionalData=record {order important for marshaling}
  ExampleData0:Real;   {00}
  ExampleData1:Real;   {01}
  ExampleData2:String; {02} 
end;

JSON representation: "AnalysisAdditionalData":[0,1,"ExampleString"]

Data structure - Interation x, 5 years later:

TAnalysisAdditionalData=record {order important for marshaling}
  ExampleData0:Real;   {00}
  ExampleData1:Real;   {01}
  ExampleData2:String; {02} 
  ExampleData3:String; {03} {since version 2016-01-01}  
  ExampleData4:String; {04} {since version 2018-01-01}  
  ExampleData5:String; {05} 
end;

JSON representation: "AnalysisAdditionalData":[0,1,"ExampleString0","ExampleString1","ExampleString2","ExampleString3"]

After interation 1 three string fields have been added. But if I now confront the standard marshal of Delphi Sydney (No custom converter, reverter, etc.) with an old dataset, so concretely with the data "AnalysisAdditionalData":[0,1, "ExampleString"], Sydney throws an EArgumentOutOfBoundsException because the 3 strings are expected - the deserialization fails.

Exit point is in Data.DBXJSONReflect in method TJSONUnMarshal.JSONToTValue - location marked below:

function TJSONUnMarshal.JSONToTValue(JsonValue: TJSONValue;
  rttiType: TRttiType): TValue;
var
  tvArray: array of TValue;
  Value: string;
  I: Integer;
  elementType: TRttiType;
  Data: TValue;
  recField: TRTTIField;
  attrRev: TJSONInterceptor;
  jsonFieldVal: TJSONValue;
  ClassType: TClass;
  Instance: Pointer;
begin
  // null or nil returns empty
  if (JsonValue = nil) or (JsonValue is TJSONNull) then
    Exit(TValue.Empty);

  // for each JSON value type
  if JsonValue is TJSONNumber then
    // get data "as is"
    Value := TJSONNumber(JsonValue).ToString
  else if JsonValue is TJSONString then
    Value := TJSONString(JsonValue).Value
  else if JsonValue is TJSONTrue then
    Exit(True)
  else if JsonValue is TJSONFalse then
    Exit(False)
  else if JsonValue is TJSONObject then
    // object...
    Exit(CreateObject(TJSONObject(JsonValue)))
  else
  begin
    case rttiType.TypeKind of
      TTypeKind.tkDynArray, TTypeKind.tkArray:
        begin
          // array
          SetLength(tvArray, TJSONArray(JsonValue).Count);
          if rttiType is TRttiArrayType then
            elementType := TRttiArrayType(rttiType).elementType
          else
            elementType := TRttiDynamicArrayType(rttiType).elementType;
          for I := 0 to Length(tvArray) - 1 do
            tvArray[I] := JSONToTValue(TJSONArray(JsonValue).Items[I],
              elementType);
          Exit(TValue.FromArray(rttiType.Handle, tvArray));
        end;
      TTypeKind.tkRecord, TTypeKind.tkMRecord:
        begin
          TValue.Make(nil, rttiType.Handle, Data);
          // match the fields with the array elements
          I := 0;
          for recField in rttiType.GetFields do
          begin
            Instance := Data.GetReferenceToRawData;
            jsonFieldVal := TJSONArray(JsonValue).Items[I]; <<<--- Exception here (EArgumentOutOfBoundsException)
            // check for type reverter
            ClassType := nil;
            if recField.FieldType.IsInstance then
              ClassType := recField.FieldType.AsInstance.MetaclassType;
            if (ClassType <> nil) then
            begin
              if HasReverter(ClassType, FIELD_ANY) then
                RevertType(recField, Instance,
                  Reverter(ClassType, FIELD_ANY),
                  jsonFieldVal)
              else
              begin
                attrRev := FieldTypeReverter(recField.FieldType);
                if attrRev = nil then
                   attrRev := FieldReverter(recField);
                if attrRev <> nil then
                  try
                    RevertType(recField, Instance, attrRev, jsonFieldVal)
                  finally
                    attrRev.Free
                  end
                else
                 recField.SetValue(Instance, JSONToTValue(jsonFieldVal,
                      recField.FieldType));
              end
            end
            else
              recField.SetValue(Instance, JSONToTValue(jsonFieldVal,
                  recField.FieldType));
            Inc(I);
          end;
          Exit(Data);
        end;
    end;
  end;

  // transform value string into TValue based on type info
  Exit(StringToTValue(Value, rttiType.Handle));
end;

Of course, this may make sense for people who, for example, only work with Sydney or at least with Delphi versions above Seattle or have started with these versions. I, on the other hand, have only recently been able to make the transition from Seattle to Sydney. Delphi Seattle has no problems with the missing record fields. Why should it, when they can be left untouched as default? Absurdly, however, Sydney has no problems with excess data.

Since it seems that the Embarcadero forum has been closed, I ask the question here: Is this a known Delphi Sydney bug? Can we expect a fix? Or can the problem be worked around in some other way, i.e. compiler directive, Data.DBXJSONReflect.TCustomAttribute, etc.? Or is it possible to write a converter/reverter for records? If so, is there a useful guide or resource that explains how to do this? I for my part have unfortunately not found any useful information in this regard, only many very poorly documented class descriptions.

I would be very happy if someone could help me.





Java: How to select/call a function by a strings content?

I have a list and I have functions.

I want to iterate the list and call the function that matches the lists element. How can I do that in a more elegant way than comparing the name in a if or switch?

class C
{
  String [] lst = {"foo", "bar", "zoo"};

  void foo () { /* ... */ }
  void bar () { /* ... */ }

  void NotSoElegant ()
  {
    for (String s : lst)
    {
      if (s.equals ("foo") == true)
      { foo (); }
      if (s.equals ("bar") == true)
      { bar (); }
    }
  }
}




mardi 26 janvier 2021

Compose SQL queries with constraints using natural logical expressions in Go

I like being fancy. Go doesn't really let you get too fancy. I recognize that it's quite intentional. Still...

I am writing a database interface library, and one of my goals is to use inferences about Go-like logical expressions to compose SQL, with some amount of runtime validation and some basic compile-time validation. There are already libraries that provide an API that looks familiar to a SQL pro, and there are a few thin wrappers like SQLX that just "grease the wheels" as it were. What there is not, to my knowledge, is a library with an API that allows the consumer to use Go-like expressions to compose queries.

This is targeted for an ecosystem where Go is the server language. I do some personal stuff in Rust, and macros would render this an absolute non-issue. I could write this so fast in Rust. Go is a different thing entirely.

The Go AST package looks like it provides a similar kind of tokenized, analyzable representation of code as does the proc_macro::TokenStream crate, which would allow the below "desired API" to be completely achievable. The problem is that I'm writing a library, and cannot depend on knowing the path of the file that's importing it. Even operator overloading, a very common language feature, is missing from Go (intentionally, I know, but on an ill-conceived rationale).

In the below example, I'm using reflection to guess what fields would exist on the in[] types used for the anonymous functions, and using a pseudo-operator representation of logical operations that compares pointer references to know what fields are being used in such operations, and whether Go values known in advance are being used for comparison.

The "Truth" interface returned by the pseudo-operator functions is evaluated into SQL logical expression, with the pointer addresses resolved into a string fieldname from the struct type passed in the argument by comparing pointer addresses between fields of a dummied zero-value struct of passed type and the arguments given to the pseudo-operator, unless the argument is another Truth interface, in which case recursion.

If I were writing in Rust, I just provide a transliteration macro, parse the TokenStream, and create equivalent SQL. But It's a library for a Go project, not Rust...

Note that these examples rely on extremely heavy use of reflection to do exactly the kinds of things Go was not meant to do.

Again, remember that the below composes two SQL statements, and reduces them into an array of objects, each having an array of objects.

    person, _ := source.Get("person") //fetch table metadata
    quirk, _ := source.Get("quirks") //fetch other table metadata
    //pretend I'm actually error checking them

    var personArray []Person

    _ := person.Filter(
        func(personRow Person) Truth { //defined type that represents a row in person table. Reflect...
            return Equality(&personRow.TookAssessment, literal(1))
        },
        //error handle-ey function, ala Javascript Promise
    ).Attach(
        quirk,
        func(personRow Person, quirkRow Quirk) Truth {
            return All(
                Equality(&quirkRow.IsActive,Literal(1)),
                Equality(&quirkRow.PersonId, &personRow.PersonId),
            )
        },
    ).Execute().Collect(&personArray)
    //pretend I'm collecting a possible error value returned and properly handling it.

That's what I'm working towards implementing it. I need not tell you that the above is cumbersome and fragile. It's not entirely clear that it only works if the consumer supplies references. It's like an exercise in "principle of MOST astonishment."

I want a way to use native Go logic in the expression, but I can't see a way to do any better than I demonstrate above.





Passing a struct method as an argument in Golang

I am not sure if I'm trying to exceed the limits of what Go will allow, but here is the context: I have type called Map with a hefty number of helpful member functions, such as Interpolate, Add, and Clear. I also have a struct type, Layered, that contains several Maps.

type Map [][]float64

func (m Map) Interpolate(min, max float64) { ... }
func (m Map) Add(val float64) { ... }
func (m Map) Clear() { ... }

type Layered struct {
    data []Map
}

I would like to add a member function to Layered that accepts any member function of Map as an argument, and then calls it on all of its contained Maps. Something along the lines of:

func (l Layered) MapCall(callMe func(Map)) {
    for _, m := range l.data {
        callMe(m)
    }
}

This partially works, but only for member functions of Map that take no additional arguments, such as Clear. Is it at all possible to accept any member function of Map as an argument (along with its potential parameters in the form of an ...interface{}), and then call the function, with its correct parameters, on all of the member Maps in a Layered? Something like this, for example:

func (l Layered) MapCall(callMe func(Map, ...interface{}), params ...interface{}) {
    for _, m := range l.data {
        callMe(m, params...)
    }
}




Kotlin smart cast to non-nullable type and ::class syntax not working together as expected

I'm trying to understand what's going on with the following code snippet (extracted from a larger project), in which I manipulate a value returned from a Java superclass. The value has type T, unbounded in Java, so it is mapped (I guess) to a platform type T! which I am treating as if it where a T?.

when (val value = node.getConcentration(molecule)) { // it's a Java method returning an unbounded generic T
    is Number -> value.toDouble()
    is String -> value.toDouble()
    is Time -> value.toDouble()
    null -> 0.0 // null has been ruled out, now Kotlin should smart-cast
    else -> throw IllegalStateException(
        "Expected a numeric value in $molecule at node ${node.id}, " +
            "but $value of type ${value::class.simpleName} was found"  // THIS IS THE RELEVANT LINE
    )
}

I would expect this to work, but I get an error on the type lookup: Expression in a class literal has a nullable type 'T', use !! to make the type non-nullable. It looks to me like Kotlin does not understand that since the null case has ben ruled out, the runtime type must be a subclass of Any.

However, it gets stranger:

when (val value = node.getConcentration(molecule)) {
    is Number -> value.toDouble()
    is String -> value.toDouble()
    is Time -> value.toDouble()
    null -> 0.0 // null has been ruled out, now Kotlin should smart-cast
    else -> throw IllegalStateException(
        "Expected a numeric value in $molecule at node ${node.id}, " +
            "but $value of type ${value!!::class.simpleName} was found" // THIS IS THE RELEVANT LINE
    )
}

This compiles, but besides being ugly, this one raises (correctly, IMHO) a warning: Unnecessary non-null assertion (!!) on a non-null receiver of type T -- but this means that the smart casting is work as expected!

I am currently solving as follows:

when (val value = node.getConcentration(molecule)) { 
    is Number -> value.toDouble()
    is String -> value.toDouble()
    is Time -> value.toDouble()
    null -> 0.0
    else -> throw IllegalStateException(
        "Expected a numeric value in $molecule at node ${node.id}, " +
            "but $value of type ${value.let { it::class.simpleName }} was found"
    )
}

This one compiles with no warning, and it is all in all a tolerable amount of boilerplate, but I can't find any reason for value::class.simpleName for raising errors, especially given that if I enforce non-nullability I get an expected warning.

Does anyone understand what's going on here? Is this a bug in Kotlin? I could not find any specific reference to this issue (by the way I'm on 1.4.21).





How to auto-register a generic interface to non generic implementations of that interface with Unity

I have a pattern going in my app.

public interface ICommandService<TCommand>
{
    public void Execute(TCommand command);
}

This interface is implemented by many different service classes. Here is an example:

public class UpdateWidgetService : ICommandService<UpdateWidget>
{
    public void Execute(UpdateWidget command)
    {
        ...
    }

}

public class UpdateWidget
{
    ...data
}

These service classes are being depended upon in controllers and other classes:

public class WidgetController
{
    private readonly ICommandService<UpdateWidget> service;
    
    public WidgetController(ICommandService<UpdateWidget> service)
    {
        this.service = service;
    }
    
    public ActionResult UpdateWidget(UpdateWidgetViewModel viewModel)
    {
        ...
        UpdateWidget command = viewModel.Command;
        this.service.Execute(command);
    }

}

If I am to register all type mappings manually I think that something like this would work:

container.RegisterType(typeof(ICommandService<UpdateWidget>), typeof(UpdateWidgetService));
container.RegisterType(typeof(ICommandService<CreateWidget>), typeof(CreateWidgetService));
container.RegisterType(typeof(ICommandService<DeleteGizmo>), typeof(DeleteGizmoService));
container.RegisterType(typeof(ICommandService<LaunchNuclearStrike>), typeof(LaunchNuclearStrikeService));

But as you can see there is a convention where all classes that implement ICommandService<TCommand> are named [TCommand]Service and I would really like to setup some kind of auto-registration by convention. Nothing I have tried so far as worked. My problem seems to be mainly with the generic type argument. Here is what I have so far:

var container = new UnityContainer();
var assembly = Assembly.GetExecutingAssembly();
var commandServices = assembly.GetTypes().Where(type => !type.IsAbstract && type.Name.EndsWith("Service") && type.GetInterfaces().Single().Name.StartsWith("ICommandService")).ToList();

foreach (var service in commandServices)
{
    var serviceInterface = service.GetInterfaces().Single();
    var genericTypeArgument = serviceInterface.GenericTypeArguments.Single();
    container.RegisterType(typeof(ICommandService<genericTypeArgument>), service);
}

I'm getting the following error: "'genericTypeArgument' is a variable but is used like a type".





How to automatically print all parameter values of Java function at runtime

I want to print automatically all the parameter values of my functions at runtime.

Just imagin that I have the following two methods:

public void doAction(String firstParam, String SecondParam) {
    Util.printAllParameter(this);
}

public void doAction(String firstParam) {
    Util.printAllParameter(this);
}

If I call to this functions:

doAction("a", "b"); --> Desired result: Print "a, b"

doAction("a"); --> Desired result: Print "a"

I don't want something like this (This is not reusable, it is static):

System.out.println(firstParam + "," + SecondParam);

I need a reusable method that I can use in different functions with different number of parameter. I want to call a function like "Util.printAllParameter()" and then print all the parameters.

Thanks in advance.





How to deserialize a complex json-object?

Good day. Please help. Let's say there is such a complex object

Map<String, List<Map<Integer, Map<String, List<String>>>> complex;

It's easy to serialize it:

String json = objectMapper.writeValueAsString(complex)

but how do I deserialize it? How can I save all the types specified.

Is something like that possible? There is a class "Foo" with the method "getComplexObject"

class Foo {
    public Map<String, List<Map<Integer, Map<String, List<String>>>> getComplexObject() {
        return null;
    }
}

Then I can get the method object and the return type of the method, for further saving and deserialization:

ParameterizedType genericReturnType = (ParameterizedType)Foo.getClass().getMethod().getGenericReturnType();
Type actualTypeArgument = genericReturnType.getActualTypeArguments()[0];

and then I can expand the type a bit:

JavaType javaType = objectMapper.getTypeFactory().constructType(actualTypeArgument);

which I will use during deserialization.

Can I somehow save the detailed type of the object so that the result is the same as when using the getComplexObject method?





lundi 25 janvier 2021

How to pass template of Anythings as template parameter in C++?

To have any types in template one may just write template <typename ...> struct S {};.

To have any values (e.g. int values) in template one may write template <auto ...> struct S {};.

To have template of any types in template one writes template <template <typename ...> class Tmpl> struct S {};.

But how to have template of Anythings in template? Anythings meaning 1) types or 2) values or 3) other templates of Anythings? I.e. mix everything what is possible inside template.

I.e. how to write template <template <Anything ...> class Tmpl> struct S {};

types/values/templates can be mixed in any order inside Tmpl parameters list.

One use case for having such structure S that accepts any kind of template is to implement template traits, i.e. so that S can tell somehow 1) how many parameters Tmpl has. 2) for each of parameter (by index) it can tell if it is type or value or another template.

Another use case for S is that it is needed to implement rich compile time information. I.e. if I can tell all the information about passed-in template, how many and what params it has, then I can compose composite Type Id or Type Name recursively and thus have compile time type reflection.

Also I'm interested in knowing how to intermix at least types and values inside one template in arbitrary order? I.e. how to have template <TypeOrValue ... Args> struct S {};? Here TypeOrValue signifies either typename or auto in any order or count.





How to retrieve a property of an object from a string?

In order to use it as a selector in a Grouping Clause at runtime, I want basically retrieve a property from an object T by passing its name. Example with this class:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime Birthday { get; set; }
}

I want to use my method like this:


private void MyMethod(string propertyName)
{
    var lambda = GetLambdaExpression(propertyName);

    // The problem is to specify the Type at compile time...
    var selector = GetLambdaSelector<DateTime>(lambda); // Seems mandatory to convert LambdaExpression to Expression<Func<Person, T>> to use in a grouping clause
    
    var result = emps.GroupBy(
        selector.Compile(),
        p => p.Birthday,
        (key, g) => new { PersonName = key, = g.ToList() }).AsQueryable();
}

Here are methods statements :

        LambdaExpression GetLambdaExpression(string propertyName)
        {
            var type = typeof(Person); 

            var propertyInfo = type.GetProperty(propertyName);
            var propertyType = propertyInfo.PropertyType;

            var entityType = propertyInfo.DeclaringType;
            var parameter = Expression.Parameter(entityType, "entity");
            var property = Expression.Property(parameter, propertyInfo);
            var funcType = typeof(Func<,>).MakeGenericType(entityType, propertyInfo.PropertyType);
            var lambda = Expression.Lambda(funcType, property, parameter);
            return lambda;
        }

        Expression<Func<Person, T>> GetLambdaSelector<T>(LambdaExpression expression)
        {
            return (Expression<Func<Person, T>>)expression;
        }

I'm stuck because I want to resolve the type (DateTimein the example) at runtime and not at compile time.

So how to call this method with type resolve at runtime: GetLambdaSelector<?>(lambda); ?

Or maybe can I change the signature of LambdaExpression GetLambdaExpression(string propertyName) to Expression<Func<Person, T>> with reflection but I did not manage it for the moment. ?





dimanche 24 janvier 2021

Is reflection on Metatype?

While it's possible to get a list of properties from an instance: it requires an instance which is troublesome if the Type isn't trivial and doesn't have a straightforward .init(). Similarly, can't we test the existence of a nested type?

struct SomeStruct: Codable {
    var x: Int
    var y: Int
}
class CoolClass: Codable {
    var thing: SomeStruct
    var name: String
    enum CodingKeys: String, CodingKey {
        case name = "title", name = "stuff"
    }
}

func testA(_ type: Any.Type) {
    if type is Codable.Protocol {
        print("is Codable")
    } else {
        print("is NOT Codable")
    }
    let mirror = Mirror(reflecting: type)
    mirror.children  // << empty collection!!
}

func testB<T>(_ type: T.Type) where T: Codable {
    // test if `type` defines `CodingKeys` or if it is synthesized.
    
}

testA(SomeStruct.self)  // "is NOT Codable", can't get list of ["x", "y"]
                        // , nor can't get CodingKeys...

If there is no reflection for metatypes, my attempts at piggybacking off of Codable's CodingKeys (explicit or synthesized) have all failed. Is this possible?





Cast object to Task

It's a little bit difficult to explain, I apologies for that. But I need help. I'm working on generic approach for events. All my code base on eShopOnContainers example but my handlers should return a value.

In eShopOnContainers there is just Task as a return type, so they can easy

var eventType = _subsManager.GetEventTypeByName(eventName);
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });

Let's say I have

public interface IRequestMessageHandler<in TRequest, TReply>
    {
        Task<TReply> Handle(TRequest request);
    }

In my case, I need to cast to Task<T>. Type for T store in variable

Type concreteHandlerType = typeof(IRequestMessageHandler<,>).MakeGenericType(subscription.RequestType, subscription.ReplyType);
Type concreteReplyType = typeof(Task<>).MakeGenericType(subscription.ReplyType);

Then I need cast result to concreteReplyType

var reply = await (concreteReplyType)concreteType.GetMethod("Handle")?.Invoke(handler, new[] { integrationEvent });

Please help me because I don't understand how it is possible. Thank you in advance. Please let me know what information should I add to help you more understand.

Fiddle with code to reproduce https://dotnetfiddle.net/X3m4A1





Cannot deserialize int List

I have a scenario that should be really simple but it isnt!

I have a type that is determined at runtime

I want to call

JSonConvert.DeserialiseObject<List<type>>(json);

via Make Generic Method as I need to determine the type at runtime

var entityTypes = _dbContext.Model.GetEntityTypes();
foreach (var entityType in entityTypes)
{
    var requiredType = entityType.ClrType;
    var testMethod = typeof(JsonConvert).GetMethods().FirstOrDefault(
       x => x.Name.Equals("DeserializeObject", StringComparison.OrdinalIgnoreCase) &&
         x.IsGenericMethod && x.GetParameters().Length == 1)
         ?.MakeGenericMethod(requiredType);

    var filename = $"my json.json";
    var json = File.ReadAllText(filename);
    var actualData2 = testMethod?.Invoke(null, new object[] { json });
}

This works perfectly if my json is for a single object

However, this is not the case, my json is for a list obviously the code above wont work because it expects my json to be a single object

So I tried to change to

var requiredType = typeof(List<entityType.ClrType>);

and entityType cannot resolved

What am I doing wrong? Sorry but I find generics really frustrating!

My ideal option was to be able to take a list of objects and convert that into a list of the required type but I cant get that to work in a generic way either hence having to try this

Cheers

Paul





Roslyn dynamic lambda compilaton and execution

I need some help in understanding about Roslyn (i am new about that technology). In my scenario i have a set of rule, each rule is a string that contain the text of a lambda expression; each lambda take an object as input and get a string as output.

Rule example :

obj => obj.ToString()

My goal is to compile each lambda once (at program startup) and then execute it with the different parameter i get (a runtime) each time.

So from what i have read i think i need to start compiling the lambda first :

            foreach ( var rule in rules )
            {
                //_formattingRules -> a dictionary that will hold all compiled lambda
                if ( string.IsNullOrEmpty(rule) == false && _formattingRules.ContainsKey ( rule ) == false )
                {
                    try
                    {
                        var currentOption = ScriptOptions.Default.AddReferences(property.PropertyType.Assembly)
                                                                 ...other refereces;


                        var script = CSharpScript.Create<Func<object, string>>(rule, options: currentOption);
                        _formattingRules.Add(rule, script);
                    }
                    catch (Exception err)
                    {
                        //error handling
                    }           
                }
            }

Then when i need to use a specific rule on object :

                    if (_formattingRules.ContainsKey(rule) == true)
                    {
                        var currentRule = _formattingRules[rule];

                        if (currentRule != null)
                        {
                            string formattedResult = currentRule.DynamicInvoke(new object [] {objectToFormat});
                        }
                    }

The problem is that when i do so, the DynamicInvoke throw a TargetParameterCountException and that let me think i am invoking the wrong thing. So i belive there is something in my understanding of how Roslyn work that is faulty, and i would like help to figure it out how to achieve a compilation first (once) with multiple execution (different parameter) of a lambda expression.





samedi 23 janvier 2021

Use reflection to call DbSet methods not working Ef Core

I have a DbContext with a property Countries

public DbSet<Country> Countries { get; set; }

I want to use reflection to call the ToListAsync method

var testMethod = this.Countries.GetType().GetMethod("ToListAsync");
var result = (Task<List<BaseEntity>>)testMethod?.Invoke(this.Countries, null);
if (result != null)
    await result;

This fails at the first hurdle when TestMethod is null

What am I doing wrong?

I am using Ef Core for .NET Core 3.1

Im working towards a method that will take a snapshot of all the tables in a DbContext including filtering expressions

I havent got to the expression part yet because of this method issue but any advise on that would be great

I am going to pass in a dictionary to this snapshot method where the key is the type name and the value is an expression

if the dictionary doesnt contain the type being analysed I will simply need to call the equivalent of

var result = await Countries.ToListAsync()

if the dictionary does contain an expression I need to call Countries.Where().ToListAsync()

Can anyone help please?

Paul





Java reflection load class from test package

I have this structure:

│   build.gradle
└───src
    ├───main
    │   └───java
    │          Main.java
    └───test
        └───java
               Test1.java

Main.java:

public class Main {

    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> testClass = Class.forName("test.Test1");
    }
}

In main method I want get metadata of Test1 class, which place in test package. But, I get this error:

Exception in thread "main" java.lang.ClassNotFoundException: test.Test1
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:377)
    at Main.main(Main.java:4)

How I can get access to classes in test package?

UPDATE: enter image description here enter image description here





vendredi 22 janvier 2021

How to convert a reflect.SliceHeader to a reflect.Value with kind Slice

I have an array for which I know the size but not the type at runtime. I would like to convert this array to a reflect.Value with kind Slice, so that I could loop over it.

I have created a reflect.SliceHeader like this:

p := uintptr(unsafe.Pointer(&array))
var data = reflect.SliceOf(originType)
sh := (*reflect.SliceHeader)(unsafe.Pointer(&data))
sh.Data = p
sh.Len = size
sh.Cap = size
runtime.KeepAlive(array) // inform garbage collector not to free the array memory

If I wanted to convert it back to a Slice of known type T, I would do:

var slice = *(*[]T)(unsafe.Pointer(sh))

But I my case, I don't know the type. How can I convert this reflect.SliceHeader to a reflect.Value with Kind Slice, so that I could continue to be generic over the underlying type?





Detect generic method parameter types

I have a MethodInfo of some generic method definition (e.g. IEnumerable<TResult> Select<TSource,TResult> (this IEnumerable<TSource> source, Func<TSource,int,TResult> selector)) and a list of parameter types IReadOnlyList<Type>. I need a method:

MethodInfo? DetectAndMakeGeneric(MethodInfo info, IReadOnlyList<Type> parameterTypes);

that will find if there is any possible specific combination for generic parameters so that I can call the method by using a list of parameters of specified types. If not possible, method should return null.

In other words something like C# compiler is doing to automatically resolve generic parameter from parameter types.





Debugger shows wrong value of static variable when set by reflection

When I set a static bool field to true using reflection and I use it in an if-statement, the debugger shows true but the logic sees false.

Does anyone know whats happening here?


static class TestClass
{
    public static void SetValueUsingReflection()
    {
        var aField = typeof(TestClass).GetField(nameof(MyBool));
        aField.SetValue(null, true);
    }
    public static readonly bool MyBool;
}

class Program
{
    static void Main(string[] args)
    {
        TestClass.SetValueUsingReflection();

        if (TestClass.MyBool) // Debugger says "True"
        {
        }
        else
        {
            // Program steps in here
        }

    }
}





UnsupportedEncodingException is not getting thrown, if we change final property value using reflection

    package com.java.random.practice;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;


    public class App 
    {
        private static final String ENCODING = "\\UTF-8";
        public static void main( String[] args ) throws UnsupportedEncodingException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
        {      
           URLEncoder.encode("anyValue", ENCODING);
        }
    }

Above code throws exception UnsupportedEncodingException when use "\" with encoding but when we use Reflection to modify the value then it does not show any exception, please see the below code:

package com.java.random.practice;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URLEncoder;


public class App 
{
    private static final String ENCODING = "UTF-8";
    public static void main( String[] args ) throws UnsupportedEncodingException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
    {      
        
          App app=new App(); 
          Field field = app.getClass().getDeclaredField("ENCODING");
          field.setAccessible(true); 
          Field modifiersField =
          Field.class.getDeclaredField("modifiers");
          modifiersField.setAccessible(true); modifiersField.setInt(field,
          field.getModifiers() & ~Modifier.FINAL); field.set(null, "\\UTF-8");
         
       String s= URLEncoder.encode("anyValue", ENCODING);
       System.out.println(s);
    }
}

Why this kind of strange behavior?





Applying NonAction to controller method according to implemented interfaces

Here is my synchronisation controller, it allows to push and/or pull data.

public class SyncController : MyController
{
  ISyncable _sync;

  public SyncController(ISyncable sync) { _sync = sync; }

  [HttpPost, PullAction]
  public async Task<IActionResult> pull()
  {
    (_sync as IPullable).Pull();
  }

  [HttpPost, PushAction]
  public async Task<IActionResult> push()
  {
    (_sync as IPushable).Push();
  }
}

If ISyncable implements IPushable, controller shall provide the push method`.

If ISyncable implements IPullable, controller shall provide the pull method`.

So I'd like to apply [NonAction] attribute according to implemented interfaces.

I intend to do it with custom attributes:

[AttributeUsage(validOn: AttributeTargets.Method, AllowMultiple = false)]
public class PushActionAttribute : Attribute
{
    public PushActionAttribute([CallerMemberName] string propertyName = null)
    {
        Type syncType = ???;  // TODO get ISyncable type from propertyName
        bool isPushable = typeof(IPushable).IsAssignableFrom(syncType);

        if(!isPushable)
        {
          // TODO apply NonActionAttribute
        }
    }
}

[AttributeUsage(validOn: AttributeTargets.Method, AllowMultiple = false)]
public class PullActionAttribute : Attribute
{
    public PullActionAttribute([CallerMemberName] string propertyName = null)
    {
        Type syncType = ???;  // TODO get ISyncable type from propertyName
        bool isPullable = typeof(IPullable).IsAssignableFrom(syncType);

        if(!isPullable)
        {
          // TODO apply NonActionAttribute
        }
    }
}

Is it possible to retrieve syncType from attribute target?

Is it possible to apply [NonAction] attribute dynamically?

Is there a better way to implement this functionality?





jeudi 21 janvier 2021

Is there a way to query properties, by name, of a DbSet, by name?

We have a large number of entities which contain user ID properties, I've created a custom attribute UserIdAttribute to annotate those models. For example:

public class MyEntity
{
  [UserId]
  public Guid Owner { get; set; }
}

We'll have a background service whose intention is to find user ID properties across all entities and perform lookups on them to populate another table. We'd like to find these values dynamically since the state of our models/application are undergoing constant change. I know I can achieve what I want using Microsoft.Data.SqlClient as below:


var allUserIds = new List<Guid>();

foreach (var entityType in dbContext.Model.GetEntityTypes())
{
  foreach (var property in entityType.GetProperties())
  {
    foreach var attribute in property.PropertyInfo.GetCustomAttributes())
    {
      if (attribute is MyCustomAttribute)
      {
        //
        // do this using EF & reflection
        //
        using (var connection = new SqlConnection("my_conn_string"))
        {
          try
          {
            var tableName = entityType.GetTableName();
            var command = new SqlCommand(
              $"select {property.Name} from {tableName}",
              conn);
            conn.Open();
            var reader = command.ExecuteReader();
            while (reader.Read())
            {
              Console.WriteLine($"{entityType.ClrType.Name}.{property.Name}: {reader[property.Name]}");
            }
          }
          finally
          {
            conn.Close();
          }
        }
      }
    }
  }
}

PopulateUserInfoTable(allUserIds);

We would prefer use EF here, the problem is that I can't see any way to query DbSets when I only have the string representation of the DbSet name. Is this even achievable?





Regarding Dynamic List to DataTable and Use of TypeDescriptor

I know that this question has been asked here before and a number of solutions were also suggested, however, after going through a lot of posts and trying many many suggested solutions, I was able to get the desired result using the simple code given below in **Style 3** while others failed. I wanted to ask why Style 2 failed and how Style 3 worked. I was under the impression that System.Component.TypeDescriptor is what we are supposed to use to get property names from Dynamic objects. Any information that would help me to understand will be greatly appreciated. Thank You!

public void EmailExcel([FromBody] MvJson json)
    {
        var dict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json.Json);
        dynamic dyn = dict["gridData"];
        dynamic off = dict["OfficeIdList"];
        List<dynamic> responseList = new List<dynamic>(dyn);
        List<dynamic> officeIdList = new List<dynamic>(off);
        if (officeIdList != null)
        {
            foreach (var item in officeIdList)
        {
        var gridData = responseList.FindAll(x => x.OfficeId == item.OfficeId);
        DataSet ds = new DataSet();
        DataTable dt = ToDataTable(gridData);  <<<<---ISSUE
        ds.Tables.Add(dt);
        var fd = ConvertToExcelByte(ds);    
    }

**<<<<< STYLE 1 >>>>>>**
        public DataTable ToDataTable<T>(List<T> items)
        {
            DataTable dataTable = new DataTable(typeof(T).Name);
            <<<<<ISSUE>>>>>
            PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo prop in Props)
            {
                dataTable.Columns.Add(prop.Name);
            }
            foreach (T item in items)
            {
                var values = new object[Props.Length];
                for (int i = 0; i < Props.Length; i++)
                {

                    values[i] = Props[i].GetValue(item, null);
                }
                dataTable.Rows.Add(values);
            }
            return dataTable;
        }

**<<<<< STYLE 2 >>>>>>**
        public static DataTable ToDataTable<T>(List<T> items)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
            {
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            }
            foreach (T item in items)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                {
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                }

                table.Rows.Add(row);
            }
            return table;
        }

**<<<<< STYLE  >>>>>>**   **WORKED**
        public DataTable ToDataTable<T>(List<T> items)
        {
            var json = JsonConvert.SerializeObject(items);
            DataTable dataTable = new DataTable();
            dataTable = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
            return dataTable;
        }





Get class constructor by functional interface method signature

I know i can use constructor reference as hihger-order method's argument like this:

collection.stream().map(MyClass::new);

But I have MyClass as a variable Class<MyClass> clazz = MyClass.class. Can I use it to pass constructor reference to .map(Function) method? I want to do something like this, is there a way to do it?

Class<MyClass> clazz = MyClass.class;
collection.stream().map(clazz.getConstructor())




Find classes with same full qualified name in Java during runtime

Lets say I have a jar a.jar with a class com.company.ma.MyClass

package com.company.ma
public class MyClass {
  public void someMethod() {
    System.out.println("Hey");
  }
}

Also another jar b.jar with a class com.company.ma.MyClass but different implementation.

package com.company.ma
public class MyClass {
  public void anotherMethod() {
    System.out.println("This is different");
  }
}

The classes have the same full qualified name but they are different.

How can I find all classes in the classpath with a given full qualified name, say com.company.ma.MyClass and print it's location? In this example I'd expect two classes with name com.company.ma.MyClass in two different jars





mercredi 20 janvier 2021

Which of these two event bus architectures is the best?

I have wrote two architectures for an event bus to use in my application. The first one is based on an extensive use of interface's implementantions for every single event. It's probably the best in terms of performances, but it doesn't allow a more dynamic approach like in the second architecture. I also pasted the test classes so you can have a better understanding of how the two event bus works. This is the EventBus class of the first architecture (https://pastebin.com/pL54Emx2):

class EventBus {
 
    private val map = HashMap<KClass<Event>, PriorityQueue<EventQueueElement>>()
 
    fun dispatchEvent(event: Event){
        val list = map[event::class]
        if(!list.isNullOrEmpty()){
            list.forEach {
                it.listener.onEvent(event)
            }
        }
    }
 
    fun registerListener(eventListener: Listener, priority: EventPriority){
        val method = eventListener::class.members.first{it.name == "onEvent"}
        @Suppress("UNCHECKED_CAST")
        val eventClass = method.parameters[1].type.classifier as KClass<Event>
        var list = map[eventClass]
        if(list.isNullOrEmpty()){
            list = PriorityQueue<EventQueueElement>()
        }
        list.add(EventQueueElement(eventListener, priority))
        map[eventClass] = list
    }
 
    private class EventQueueElement(val listener: Listener, val priority: EventPriority = EventPriority.NORMAL) : Comparable<EventQueueElement>{
        override fun compareTo(other: EventQueueElement): Int {
            return priority.compareTo(other.priority)
        }
    }
 
}

And this is its test class (https://pastebin.com/bJ8p40zD):

class MyEventListener : Listener {
    override fun onEvent(event: Event) {
        print("test")
    }
}
 
internal class EventBusTest {
 
    @Test
    fun registerListener(){
        val myListener = MyEventListener()
        val eventBus = EventBus()
        assertDoesNotThrow {
            eventBus.registerListener(myListener,EventPriority.NORMAL)
        }
    }
 
    @Test
    fun dispatchEvent(){
        val myListener = MyEventListener()
        val eventBus = EventBus()
        eventBus.registerListener(myListener,EventPriority.NORMAL)
        val event = Event()
        assertDoesNotThrow {
            eventBus.dispatchEvent(event)
        }
    }
}

Instead, with the second architecture I can create infinite methods inside the same Listener implementation, but they must have the annotation @EventHandler and only have one parameter of type Event.
Here's the second implementation of the EventBus (https://pastebin.com/3KmQYLab):

class EventBus {
 
    private val map = HashMap<KClass<Event>, PriorityQueue<EventQueueElement>>()
 
    fun dispatchEvent(event: Event){
        val list = map[event::class]
        if(!list.isNullOrEmpty()){
            list.forEach { element ->
                val listener = element.listener
                listener::class.members.forEach{ method ->
                    if(method.hasAnnotation<EventHandler>() && method.parameters.size == 2){
                        @Suppress("UNCHECKED_CAST")
                        if(method.parameters[1].type.classifier as KClass<Event> == event::class){
                            method.call(listener, event)
                        }
                    }
                }
            }
        }
    }
 
    fun registerListener(eventListener: Listener, priority: EventPriority){
        val hashSet = HashSet<KClass<Event>>()
        eventListener::class.members.forEach{method ->
            if(method.hasAnnotation<EventHandler>() && method.parameters.size == 2){
                @Suppress("UNCHECKED_CAST")
                val eventClass = method.parameters[1].type.classifier as KClass<Event>
                if(!hashSet.contains(eventClass)) {
                    hashSet.add(eventClass)
                    var list = map[eventClass]
                    if(list.isNullOrEmpty()){
                        list = PriorityQueue<EventQueueElement>()
                    }
                    list.add(EventQueueElement(eventListener, priority))
                    map[eventClass] = list
                }
            }
        }
    }
 
    private class EventQueueElement(val listener: Listener, val priority: EventPriority = EventPriority.NORMAL) : Comparable<EventQueueElement>{
        override fun compareTo(other: EventQueueElement): Int {
            return priority.compareTo(other.priority)
        }
    }
 
}

and of its test (https://pastebin.com/jaf9BUSC):

class MyEventListener : Listener {
 
    @EventHandler
    fun onEvent(event: RandomEventOne) {
        println("test")
    }
 
 
    @EventHandler
    fun onEventTwo(event: RandomEventTwo){
        println("test2")
    }
}
 
internal class EventBusTest {
 
    @Test
    fun registerListener(){
        val myListener = MyEventListener()
        val eventBus = EventBus()
        assertDoesNotThrow {
            eventBus.registerListener(myListener,EventPriority.NORMAL)
        }
    }
 
    @Test
    fun dispatchEvent(){
        val myListener = MyEventListener()
        val eventBus = EventBus()
        eventBus.registerListener(myListener,EventPriority.NORMAL)
        val event = Event()
        assertDoesNotThrow {
            eventBus.dispatchEvent(event)
        }
    }
}

Which architecture is the best in your opinion?





how do get a pointer to a type given a reflect.Type

I have a reflect.Type of type reflect.Struct, I want to get the reflect.Type of a Pointer to this struct. How do I go about doing this? ideally without allocating to create one.





Unable to call a KCallable after passing it to a constructor of another object

I'm trying to figure out what's wrong with this code. Basically I get a reference to a method of a class using reflection and then I try to store it in another object for later calls. The method is of the Listener object. The problem is that if try to call the function from inside that storing object, I get a mismatched type exception because it is not expecting a Listener instance but a Listener.myMethod instance.

typealias EventFunction = (Event)->Unit
val priority = method.getAnnotation(EventHandler::class.java).priority
val function = eventListener::class.members.find{it.name == methodName}!! as KFunction<EventFunction>
val eventQueueElement = EventQueueElement(priority, function, eventListener)
//Here's where the code brakes
eventQueueElement.function.call(eventQueueElement.listener, eventQueueElement.priority)

But if I call the function direclty without passing it to the EventQueueElement constructor it works

function.call(eventListener, priority)

Here's the definition of the storing object

private class EventQueueElement(val priority: EventPriority, val function: KFunction<EventFunction>, val listener: Listener) : Comparable<EventQueueElement>{
        override fun compareTo(other: EventQueueElement): Int {
            return priority.compareTo(other.priority)
        }
    }




mardi 19 janvier 2021

How to define a class at runtime that includes a call to an method of an object without a companion class?

The following Scala (2.12.12) code runs with the expected behavior. The ClassDef tree is defined using the toolbox, and a ClassSymbol is returned.

class MyObj

object MyObj {
  def foo(x: Int): Int = x
}

object Test {

  import ru._

  def main(args: Array[String]): Unit = {

    val objSymbol = ru.typeOf[MyObj].typeSymbol.companion  // This is the most important line!

    val tree = ClassDef(
      Modifiers(),
      TypeName("Program"),
      List(),
      Template(
        List(Ident(TypeName("AnyRef"))),
        noSelfType,
        List(
          DefDef(
            Modifiers(),
            termNames.CONSTRUCTOR,
            List(),
            List(List()),
            TypeTree(),
            Block(
              List(
                Apply(Select(Super(This(typeNames.EMPTY), typeNames.EMPTY), termNames.CONSTRUCTOR), List())
              ),
              Literal(Constant(()))
            )
          ),
          DefDef(
            Modifiers(),
            TermName("fn"),
            List(),
            List(),
            TypeTree(),
            Apply(Select(Ident(objSymbol), TermName("foo")), List(Literal(Constant(10))))
          )
        )
      )
    )

    val clsSymbol = Reflection.toolbox.define(tree).asInstanceOf[ClassSymbol]
  }

}

However, the class MyObj is only serving the purpose of allowing us to get the symbol of the object via ru.typeOf[MyObj].typeSymbol.companion. I have some situations where an object does not have a companion class, and I would like to modify this code so that it works without the need for class MyObj.

Here is what I have tried so far:


Attempt 1.

val objSymbol = ru.typeOf[MyObj.type].typeSymbol

Produces the following error in the compiler. I don't know how to understand it, and can't find many mentions of this kind of error outside of the Scala language developer discussions.

Exception in thread "main" scala.tools.reflect.ToolBoxError: reflective compilation has failed:


  Unexpected tree in genLoad: erp12.scala_cbgp.lang.MyObj.type/class scala.reflect.internal.Trees$TypeTree at: NoPosition
     while compiling: <no file>
        during phase: jvm
     library version: version 2.12.12
    compiler version: version 2.12.12
  reconstructed args: 

  last tree to typer: TypeTree(class Int)
       tree position: <unknown>
            tree tpe: Int
              symbol: (final abstract) class Int in package scala
   symbol definition: final abstract class Int extends  (a ClassSymbol with SynchronizedClassSymbol)
      symbol package: scala
       symbol owners: class Int
           call site: constructor Program in class Program in package __wrapper$1$78b0f9d262f74777a2e9b5209fcd5413

Attempt 2.

currentMirror.staticModule(MyObj.getClass.getCanonicalName)

Also tried with variations:

  • runtimeMirror(getClass.getClassLoader) vs currentMirror
  • MyObj.getClass.getTypeName vs MyObj.getClass.getCanonicalName (same thing in this case)

This throw a ToolBoxError with value foo is not a member of object erp12.scala_cbgp.lang.MyObj$ which leads me to believe it is returning a different symbol from the one I need.


Attempt 3.

currentMirror.staticClass(MyObj.getClass.getCanonicalName)

Yields the same result as attempt 1.


Any guidance on what I am doing wrong would be much appreciated.





How to get list of all loaded Classes by all JVM ClassLoaders, which is anotated by some anotation?

I looked at this, but this is not helpful for me. Getting a list of all classloaders in a JVM

I am making my own injecting library and I want to use annotations to markup classes which will be instantiated at injector start. Is there a way to get list of all loaded Classes by all JVM ClassLoaders, which is anotated by some anotation?

Is it possible to do this with for example "org.reflections" dependency or similar?

Thanks for your help





Getting the base type of a custom type in Go using Reflect

Say I create a custom type in Go:

type CustomTime time.Time

Using reflection, I'm comparing types, e.g.

var foo CustomTime = CustomTime(time.Now())
customType := reflect.TypeOf(foo)

timeType := reflect.TypeOf(time.Now())

if customType == timeType {
    fmt.Println("Is timeType")
} else {
    fmt.Println("Is not timeType")
}

This prints "Is not timeType". What I'm trying to do is find a way to see if the base type that the custom type uses (i.e. the time.Time in type CustomType time.Time) is of type time.Time.

I've tried using reflect's Kind() function, but that returns struct for both since time.Time is a struct.

Here's a playground with this code.





quarkus native reflection configuration for whole package

I'm building quarkus native and using Stripe sdk as external library. In order to support Stripe sdk it I needed to create reflection-config.json file and set in the application.properties quarkus.native.additional-build-args=-H:ReflectionConfigurationFiles=reflection-config.json

The reflection-config.json looks like so:

  {
    "name": "com.stripe.model.Customer",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.stripe.model.Customer$InvoiceSettings",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.stripe.model.StripeError",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.stripe.model.PaymentIntent",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.stripe.model.PaymentMethod",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  }....

and so on. It contains too many classes. My question is if there is a way to set the whole package instead of tons of classes? For example:

  {
    "name": "com.stripe.model.*",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  }

Didn't find any mention for it.





How to get a function reference using reflection in Kotlin

Let's suppose I have an instance of a class X with a method Y of which we will know the name only at runtime, how can I get a reference to it using reflection?

Something like:

class X{

  fun Y(){
    
  }

}

I want to able to store the method Y in a variable and call it when needed.

I tried with X::class.java::getMethod('Y').kotlinFunction but then I will need to have an instance of such method to be able to call it, so it doesn't make any sense





Passing a class as argument to a method, then calling static methods

I have a use case with a class existing in 2 versions of a package.

package packageV1;

public class MyClass extends BaseClass{

 public static String example(){
      return "Version1";
    }
}
package packageV2;

public class MyClass extends BaseClass{

 public static String example(){
     return "Version2";
      }
}

So far so good (I believe).

Then I have an application using that class, and to avoid rewriting the application for the different package version, I want to pass the class that should be use (ie for the package of interest) as argument to the application. So something like

public class Application{
      
      private Class<BaseClass> selectedClass;

      public void Application(Class<BaseClass> selectedClass){
               this.selectedClass = selectedClass;
               this.selectedClass.example();  // not possible
               }

}

I believe I could call this.selectedClass.example(); if I were passing an instance of MyClass in the constructor, but then I would call static methods through a instance object, not nice right ?

On the other hand, in the example above selectedClass is a Class object, so I can't call the static method example as above.

Does this mean I should use reflection ? like selectedClass.getMethod(name, parameterTypes). Looks overly complicated to me.

Or is there a better design ?





Cannot convert method group to non-delegate type with reflection

I'm attempting to automatically register request handling classes with reflection.

This is an example of manually adding a handler for execution of a certain request.

// generic manual method of registration
server.RegisterHandler<GetData>(base.ExecuteMessage);

Here is the attempt to register with reflection. The invoke method will not accept the 'ExecuteMessage' method getting the error "Error CS0428 Cannot convert method group 'ExecuteMessage' to non-delegate type 'object'. Did you intend to invoke the method?".

// registration with reflection
foreach (var type in serviceTypes)
{
    // registerHandlerMethod definition:    RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn)
    // ExecuteMessage definition:           object ExecuteMessage(IMessage message)

    registerHandlerMethod.MakeGenericMethod(type).Invoke(server, new object[] { base.ExecuteMessage });
}

Is it possible to cast the ExecuteMessage method in any way to get this to work?

Edit: Added example with problem below

class Program
{
    static void Main(string[] args)
    {
        var server = new Server();

        // generic manual method of registration
        server.RegisterHandler<GetData>(ExecuteMessage);

        // registration with reflection
        var serviceTypes = new List<Type> { typeof(GetData) };
        var registerHandlerMethod = typeof(Server).GetMethod(nameof(Server.RegisterHandler));

        foreach (var type in serviceTypes)
        {
            registerHandlerMethod.MakeGenericMethod(type).Invoke(server, new object[] { ExecuteMessage });
        }
    }

    static object ExecuteMessage(IMessage message)
    {
        return null;
    }

    internal class GetData
    {

    }

    internal interface IMessage<T> : IMessage
    {

    }

    internal interface IMessage
    {

    }

    internal class Server
    {

        internal void RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn)
        {
        }
    }
}




System.Reflection Get property as an object and set another property of the property

So, in my project, on a STL file, there are some points, when I move a point, the coordinate informations change. When a point moved, it must be marked as modified.

And when I move the point, I have the property name of the point. From the property name, I can access to the property, it returns a Custom3DPoint.

The Custom3DPoint class has a Status property.

For a clearer explanation, I have a class named A which has two properties P1 and P2. And I have another class named B which has a property of type A.

How to get the property of the object B from the propertyname P1 and set the P2 value.

Here is what I tried :

class A
{
    public string P1{ get; set; }
    public string P2 { get; set; }

    public A()
    {
        P1 = "value1";
        P2 = "value2";
    }
}

class B
{
    public A PropA { get; set; }
    public B()
    {
        PropA = new test.A();

    }
}

void Moved(B obj, string propertyName)
{
    var prop = obj.GetType().GetProperty(propertyName);
    var statusProp = prop.GetType().GetProperty("Status"); //this line returns null because

    prop.GetType().GetProperties(); // doesn't return properties of A object.

    statusProp.SetValue(prop, "modified");
}

Is it possible using Reflection ?





lundi 18 janvier 2021

c# Altering methods in parsed code in a SyntaxTree

I'm paring a string that contains a c# code using a SyntaxTree. What I would like to do is to alter the methods in the code:

  • Get the list of parameters passed to the method
  • Add lines of code to be executed by the method - some of them has to do with the parameters passed to the method.

This is my code so far:

string code = @"
public void SayHello(string name) {
    Console.WriteLine(""Hello "" + name);
}

private string SayGoodbye() {
    Console.WriteLine(""Goodbye"");
}
";

SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);

var root = syntaxTree.GetRoot();
var members = syntaxTree.GetCompilationUnitRoot().Members;

var firstMember = members[0];
Console.WriteLine(firstMember.ToString());

Console.WriteLine(syntaxTree.ToString());

firstMember contains the tree structure for the SayHello method. Using .ToString() I can get the full method string. From here what I was thinking is to take that string and parse it to get the method parameters and alter the string to add the command lines that I need. And then using reflection read that string code and execute it.

But I was wondering, is there a more correct ".NET" way of doing such alterations parsed code?





Detect which async overload is called inside a C# method using reflection

Using reflection, I need to determine which overloads a particular async method is calling. In this case, I need to inspect the DoSomething() method to determine which method calls to MyMethod() it's making.

First, consider the following C# console app for the sync version:

using System;
using System.Linq;
using System.Reflection;
using Mono.Cecil;

namespace CecilReflection
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var assemblyDefinition = AssemblyDefinition.ReadAssembly(Assembly.GetExecutingAssembly().Location);

            var toInspect = assemblyDefinition.MainModule
                .GetTypes()
                .SelectMany(type => type.Methods
                    .Where(method => method.HasBody)
                    .Select(method => new
                    {
                        Type = type,
                        Method = method
                    }))
                .Where(x => x.Method.Name == "DoSomething");

            foreach (var entry in toInspect)
            {
                Console.WriteLine($"\tType = {entry.Type.Name}\n\t\tMethod = {entry.Method.Name}");
                foreach (var instruction in entry.Method.Body.Instructions)
                    Console.WriteLine($"{instruction.OpCode} \"{instruction.Operand}\"");
            }

            Console.ReadKey();
        }

        public static void DoSomething()
        {
            var myClass = new MyClass();

            myClass.MyMethod();
            myClass.MyMethod(5);
        }

        public class MyClass
        {
            public void MyMethod()
            {
            }

            public void MyMethod(int arg)
            {
            }
        }
    }
}

Running this produces the following output:

        Type = Program
                Method = DoSomething
nop ""
newobj "System.Void CecilReflection.Program/MyClass::.ctor()"
stloc.0 ""
ldloc.0 ""
callvirt "System.Void CecilReflection.Program/MyClass::MyMethod()"
nop ""
ldloc.0 ""
ldc.i4.5 ""
callvirt "System.Void CecilReflection.Program/MyClass::MyMethod(System.Int32)"
nop ""
ret ""

By looking at the callvirt entries, I'm able to detect that both overloads of MyMethod() are called using the above code.

Here's the async version:

using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Mono.Cecil;

namespace CecilReflection
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var assemblyDefinition = AssemblyDefinition.ReadAssembly(Assembly.GetExecutingAssembly().Location);

            var toInspect = assemblyDefinition.MainModule
                .GetTypes()
                .SelectMany(type => type.Methods
                    .Where(method => method.HasBody)
                    .Select(method => new
                    {
                        Type = type,
                        Method = method
                    }))
                .Where(x => x.Method.Name == "DoSomething");

            foreach (var entry in toInspect)
            {
                Console.WriteLine($"\tType = {entry.Type.Name}\n\t\tMethod = {entry.Method.Name}");
                foreach (var instruction in entry.Method.Body.Instructions)
                    Console.WriteLine($"{instruction.OpCode} \"{instruction.Operand}\"");
            }

            Console.ReadKey();
        }

        public static async Task DoSomething()
        {
            var myClass = new MyClass();

            await myClass.MyMethodAsync();
            await myClass.MyMethodAsync(5);
        }

        public class MyClass
        {
            public async Task MyMethodAsync()
            {
            }

            public async Task MyMethodAsync(int arg)
            {
            }
        }
    }
}

This produces the following output:

        Type = Program
                Method = DoSomething
newobj "System.Void CecilReflection.Program/<DoSomething>d__1::.ctor()"
stloc.0 ""
ldloc.0 ""
call "System.Runtime.CompilerServices.AsyncTaskMethodBuilder System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Create()"
stfld "System.Runtime.CompilerServices.AsyncTaskMethodBuilder CecilReflection.Program/<DoSomething>d__1::<>t__builder"
ldloc.0 ""
ldc.i4.m1 ""
stfld "System.Int32 CecilReflection.Program/<DoSomething>d__1::<>1__state"
ldloc.0 ""
ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder CecilReflection.Program/<DoSomething>d__1::<>t__builder"
ldloca.s "V_0"
call "System.Void System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Start<CecilReflection.Program/<DoSomething>d__1>(!!0&)"
ldloc.0 ""
ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder CecilReflection.Program/<DoSomething>d__1::<>t__builder"
call "System.Threading.Tasks.Task System.Runtime.CompilerServices.AsyncTaskMethodBuilder::get_Task()"
ret ""

With the async version, I'm not able to determine anything about which overloads to MyMethodAsync() were called, if any.

Is there any way to determine which overloads to MyMethodAsync() were called? It's not a requirement that I use Mono.Cecil, but I've had even less luck using System.Reflection to accomplish this. If a completely different approach would work, that's fine.