为什么我的DynamicObject上没有调用TryGetMember?

时间:2016-12-07 20:02:14

标签: c# dynamic-language-runtime dynamicobject

我有以下类用于绑定到WPF DataGrid上动态生成的列。列绑定必须是属性名称,我可以将适当命名的属性添加到DynamicObject

public class BindableDynamicDictionary : DynamicObject
{
    private readonly Dictionary<string, object> _dictionary;

    public BindableDynamicDictionary()
    {
        _dictionary = new Dictionary<string, object>();
    }

    public object this[string key]
    {
        get { return _dictionary[key]; }
        set { _dictionary[key] = value; }
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _dictionary.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _dictionary[binder.Name] = value;
        return true;
    }
}

仅供参考,每天财产都存储AppointmentRowViewModel

当我为一周中的每一天用一个动态属性填充上面的实例时,列出了所有动态属性,并且字典访问工作正常,但属性名称访问会引发异常。例如(来自我的即时窗口):

apptDynamic.GetDynamicMemberNames()
Count = 9
    [0]: "20161205"
    [1]: "Monday"
    [2]: "20161206"
    [3]: "Tuesday"
    [4]: "20161208"
    [5]: "Thursday"
    [6]: "20161211"
    [7]: "Sunday"
    [8]: "20161215"
apptDynamic.Monday
error CS1061: 'AppointmentCalendarViewModel.TimeAppointmentDictionary' does not contain a definition for 'Monday' and no extension method 'Monday' accepting a first argument of type 'AppointmentCalendarViewModel.TimeAppointmentDictionary' could be found (are you missing a using directive or an assembly reference?)
apptDynamic["Monday"]
{ApptEase.Client.Prism.CSharp.ViewModels.AppointmentRowViewModel}

这可能是因为我只使用字典访问设置属性吗?我不知道如果没有属性名称文字,所以我这样做:

BindableDynamicDictionary apptDynamic = Appointments[start];
DateTime loopDate = ActiveDate.FirstDayOfWeek(WeekStartDay);
for (var i = 0; i < DaysVisible; i++)
{
    loopDate = loopDate.AddDays(i);
    if (appt.StartDateTime.Date == loopDate.Date)
    {
        apptDynamic[loopDate.ToString("yyyyMMdd")] = appt;
        apptDynamic[loopDate.DayOfWeek.ToString()] = appt;
        continue;
    }
    apptDynamic[loopDate.ToString("yyyyMMdd")] = null;
    apptDynamic[loopDate.DayOfWeek.ToString()] = null;
}

其中ActiveDate.FirstDayOfWeek(WeekStartDay)使用DateTime扩展程序获取ActiveDate出现在一周的第一天的日期,具体取决于本周的开始日期。

我认为DynamicObject的主要思想部分是能够使用它的密钥访问字典项,就像它是属性名一样。为什么这对我不起作用?

1 个答案:

答案 0 :(得分:3)

由于我的低代表,我无法添加评论,所以我会留下答案。

从您提供的代码示例中我只能看到您将动态对象存储为

的方式
BindableDynamicDictionary apptDynamic = Appointments[start];

要动态属性访问工作,您需要使用动态关键字

dynamic apptDynamic = Appointments[start];

参考链接

https://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.trygetmember(v=vs.110).aspx

Differences between ExpandoObject, DynamicObject and dynamic