C# DynamicObject绑定WRT私有类型

C# DynamicObject绑定WRT私有类型,c#,.net,dynamic,C#,.net,Dynamic,考虑以下几点: using System; using System.Dynamic; namespace DynamicTest { class Program { static void Main(string[] args) { dynamic d = new DynamicTest(); var v = d.foo(); Console.WriteLine(v.Val

考虑以下几点:

using System;
using System.Dynamic;

namespace DynamicTest
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic d = new DynamicTest();
            var v = d.foo();
            Console.WriteLine(v.Value);

            Console.ReadKey();
        }
    }

    public interface IValueProvider<T>
    {
        T Value
        {
            get;
        }
    }

    public class DynamicTest : DynamicObject
    {
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            result = new ValueProvider<int>(32);
            return true;
        }

        private class ValueProvider<T> : IValueProvider<T>
        {
            public ValueProvider(T t)
            {
                this.Value = t;
            }

            public T Value
            {
                get;
                private set;
            }
        }
    }
}
如果我将
ValueProvider
类更改为
public
而不是
private
,它将按预期工作:

// this allows it to work
public class ValueProvider<T> : IValueProvider<T>

有人能指出我遗漏了什么吗?有没有一种方法可以让上面的代码在不公开所有类型和不强制转换的情况下工作?

一种解决方案是让
ValueProvider
inherit
DynamicObject
,然后在此基础上实现
TryGetMember

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = this.Value;
            return true;
        }

当然,在本例中,无论您尝试获取什么属性,我们都只是返回值,但我可能会考虑使用字典或ExpandoObject来保留
ValueProvider上的可用属性。有趣的是,如果可访问性是
内部的
,它就会起作用:

internal class ValueProvider<T> : IValueProvider<T> { ... }
(在课堂上):

以及:


谢谢你的建议。然而,我的例子是高度简化的。我的界面非常复杂-它不仅仅返回一个值。为什么对您来说很奇怪,它的内部工作正常?对我来说,它看起来很简单-如果调用代码可以访问返回对象的类,它就可以工作。@Hassan-是的,很公平-它比我认为的更微妙(和正确)-我会编辑它。
// this doesn't help
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
    var valueProvider = (IValueProvider<int>)new ValueProvider<int>(32);
    result = valueProvider;
    return true;
}
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = this.Value;
            return true;
        }
internal class ValueProvider<T> : IValueProvider<T> { ... }
public interface IValueProvider
{
    object Value { get; }
}
public interface IValueProvider<T> : IValueProvider
{
    new T Value{get; }
}
object IValueProvider.Value { get { return Value; } }
var v = (IValueProvider)d.foo();
Console.WriteLine(v.Value);