gpt4 book ai didi

c# - 可以获取 DynamicObject 的链式值吗?

转载 作者:太空狗 更新时间:2023-10-29 23:24:48 26 4
gpt4 key购买 nike

创建一个实现 DynamicObject 的类

public class Test : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == ("Posts"))
{
result = "property accessed was 'Posts'";
return true;
}

return base.TryGetMember(binder, out result);
}
}

我可以打电话

dynamic test = new Test();
var result = test.Posts;

result的值为“dynamic test = new Test();var result = test.Posts;"

没关系。

我想知道的是,当调用 TryGetMember 时是否有可能获取链式值。

所以如果我调用:

dynamic test = new Test();
var result = test.Posts.Load(123);

然后我可以做类似的事情:

if (binder.Name == ("Posts"))
{
if (... == "Load")
result = this.Load<Post>(... 123);
return true;
}

这样的事情可能吗?我想不出办法。

到目前为止我有:

class Program
{
static void Main(string[] args)
{
dynamic test = new Test();
dynamic result = test.Posts.Load(123);

Console.WriteLine(result.Name);

dynamic result2 = test.Posts.Load(909);

Console.WriteLine(result2.Name);

Console.ReadKey();
}
}

public class Test : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == ("Posts"))
{
result = new ChainBuilder(this, "Post");
return true;
}

return base.TryGetMember(binder, out result);
}

public T Load<T>(int id) where T : Post, new()
{
if (id == 123)
return new T {Id = 123, Name = "Bananas"};

return new T {Id = 0, Name = "Others"};
}

private class ChainBuilder : DynamicObject
{
public dynamic OriginalObject { get; set; }
public string PropertyInvoked { get; set; }

public ChainBuilder(DynamicObject originalObject, string propertyInvoked)
{
OriginalObject = originalObject;
PropertyInvoked = propertyInvoked;
}

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "Load")
{
result = OriginalObject.Load<Post>((int)args[0]);
return true;
}

return base.TryInvokeMember(binder, args, out result);
}
}
}

public class Post
{
public int Id { get; set; }
public string Name { get; set; }
}

这要归功于 Bartosz。

但看起来这基本上是 Marc 提供的。

给我一​​个好的起点!对于任何其他建议,我暂时将其打开。

这个问题导致了

不是真正的项目,只是原型(prototype)设计但实现了我们想要的。

最佳答案

评估的每个步骤都是独立的;它不评估 .Posts.Load(123) - 它评估 .Posts,然后单独评估 .Load(123),所以没有: 你不能一步完成。诀窍是自己组合值,例如:

using System;
using System.Dynamic;
using System.Text;
static class Program {
static void Main() {
dynamic test = new Test();
var result = test.Posts.Foo.Bar(123, "abc");
Console.WriteLine(result);
}
}
public class Test : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder,
out object result)
{
result = new MemberAccessWrapper("member accessed was " + binder.Name);
return true;
}
private class MemberAccessWrapper : DynamicObject
{
private readonly string message;
public override bool TryInvoke(InvokeBinder binder, object[] args,
out object result)
{
StringBuilder builder = new StringBuilder(message).Append("(");
for(int i = 0 ; i < args.Length ; i++) {
if(i!=0)builder.Append(", ");
if (args[i] == null) {
builder.Append("null");
} else if (args[i] is string) {
builder.Append("@\"").Append(((string)args[i])
.Replace("\"", "\"\"")).Append("\"");
} else {
builder.Append(args[i]);
}
}
builder.Append(")");
result = new MemberAccessWrapper(builder.ToString());
return true;
}
public MemberAccessWrapper(string message)
{
this.message = message;
}
public override string ToString()
{
return message;
}
public override bool TryGetMember(GetMemberBinder binder,
out object result)
{
result = new MemberAccessWrapper(message + "." + binder.Name);
return true;
}
}
}

关于c# - 可以获取 DynamicObject 的链式值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12634250/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com