首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DynamicObject绑定WRT私有类型

DynamicObject绑定WRT私有类型
EN

Stack Overflow用户
提问于 2011-08-22 16:50:46
回答 2查看 187关注 0票数 2

请考虑以下几点:

代码语言:javascript
复制
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;
            }
        }
    }
}

此操作在运行时失败,出现以下错误:

代码语言:javascript
复制
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException was unhandled
  Message='object' does not contain a definition for 'Value'
  Source=Anonymously Hosted DynamicMethods Assembly
  StackTrace:
       at CallSite.Target(Closure , CallSite , Object )
       at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
       at DynamicTest.Program.Main(String[] args)
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

如果我将ValueProvider<T>类更改为public而不是private,它将按预期工作:

代码语言:javascript
复制
// this allows it to work
public class ValueProvider<T> : IValueProvider<T>

或者,如果我将结果转换为IValueProvider<int>,它也可以工作:

代码语言:javascript
复制
// this also allows it to work
dynamic d = new DynamicTest();
var v = (IValueProvider<int>)d.foo();

如果我尝试在TryInvokeMember中使用该接口作为编译时类型,它不会工作(我并没有真正期望它能工作,但我想我会试一下):

代码语言:javascript
复制
// 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;
}

有谁能指出我在这里遗漏了什么吗?有没有一种方法可以让上面的代码正常工作,而不是让我的所有类型都公开,也不需要强制转换?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-08-22 17:04:18

有趣的是,如果可访问性为internal,则可以正常工作

代码语言:javascript
复制
internal class ValueProvider<T> : IValueProvider<T> { ... }

正如Hassan所指出的(注释),这是有意义的,因为这是Program使用DynamicTest的API成员(在同一程序集中)通常所需的可访问性。如果我们将Main移到DynamicTest,并将其保留为private,它将再次工作,这是我们应该期望的正确的可访问性。

也许现在可以使用internal

当然,这里还有一个更好的方法,那就是只使用接口。在这里,您不需要dynamic;您可能需要的是一个非通用IValueProvider

代码语言:javascript
复制
public interface IValueProvider
{
    object Value { get; }
}
public interface IValueProvider<T> : IValueProvider
{
    new T Value{get; }
}

与(在班级中):

代码语言:javascript
复制
object IValueProvider.Value { get { return Value; } }

和:

代码语言:javascript
复制
var v = (IValueProvider)d.foo();
Console.WriteLine(v.Value);
票数 3
EN

Stack Overflow用户

发布于 2011-08-22 17:01:22

一种解决方案是让ValueProvider<T>也继承DynamicObject,然后在上面实现TryGetMember

代码语言:javascript
复制
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = this.Value;
            return true;
        }

当然,在本例中,无论您尝试获取什么属性,我们都只是返回值,但我可能会考虑使用字典或ExpandoObject来保留ValueProvider<T>上的可用属性

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7145029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档