night-moon-studio / Leo

A library based on NCC Natasha to quickly and easily read/write instance's fields or properties.
https://natasha.dotnetcore.xyz
MIT License
81 stars 18 forks source link

[Proposal]: get or set value by path for nested class #23

Open huoshan12345 opened 3 years ago

huoshan12345 commented 3 years ago

Hi all, Leo is a great lib. I would like to request a feature that a value can be gotten or set by path for nested class. For example

public class A
{
    public B B { get; set; }
}

public class B
{
    public string Name { get; set; }
}

[Fact]
public void Test()
{
    var a = new A { B = new B { Name = "name" } };
    var visitor = LeoVisitorFactory.Create(typeof(A), a);
    var name = visitor["B.Name"];    // get value by path
    Assert.Equal("name", name);      // make this work.
}

Thank you for consideration.

NMSAzulX commented 3 years ago

This is a good suggestion and can be implemented. But this involves the depth of the class, and the scheme may affect performance. Do you have any more detailed suggestions?

NMSAzulX commented 3 years ago

@alexinea I think we can support it on Leo. But it is not a high-performance implementation, there will be the loss of string parsing. If we put linked calls into the BTF dictionary, this will cause a lot of trouble, such as linked lists. Will this affect Typed if I store B in a new leo instance?

alexinea commented 3 years ago

We need to solve the problem of circular references:

class A{
    public B One {get;set;}
}

class B{
    public B(A a) => Two = a;

    public A Two {get;}
}

When creating the Leo instance of B, will you create the Leo instance of A again in a loop? If you give me the Leo instances of A and B at the same time, and specify the relationship between them, then it should not be a problem to add support for the Typed component.

Maybe we can use an interface like v["B", "name"]

I think this requirement is great. We can try it.

NMSAzulX commented 3 years ago

V ["B", "name"] this has changed the user's original intention, they hope that B.name, in fact, string parsing and new leo objects have lost performance, maybe we need to use the BTF dictionary to learn the user's calls and dynamically generate delegates.

NMSAzulX commented 3 years ago

@huoshan12345 After discussion, this feature will be transferred to LeoVisitor. The Leo layer will not support this feature because Leo is currently a complete minimum operating unit. If the relevant code is not configured, this feature may upset the existing performance balance. This feature brings high complexity.

huoshan12345 commented 3 years ago

@NMSAzulX Thanks very much. That's will be exciting if this feature is added.

huoshan12345 commented 3 years ago

Some ideas:

alexinea commented 3 years ago

We supported it experimentally. The current limited support is the form A.B.C for the GetValue method

Like: image

Currently, this feature does not support arrays, nor does it support the SetValue method (this involves synchronization of objects).

alexinea commented 2 years ago

We have implemented this feature experimentally. It can be viewed in Alex's Cosmos-OV. This feature has not yet been merged into Leo.Typed as we need further evaluation.