我在CallForm FormDialog中使用了以下枚举:
public enum CallTimeOptions
{
[Describe("tonight")]
[Terms("tonight", "this evening", "pm", "this pm")]
Tonight = 1,
[Describe("tomorrow morning")]
[Terms("tomorrow morning", "tomorrow am", "am")]
TomorrowMorning,
[Describe("tomorrow noon time")]
[Terms("tomorrow noon time", "tomorrow noon", "tomorrow lunch", "lunch")]
TomorrowNoonTime,
[Describe("tomorrow evening")]
[Terms("tomorrow evening", "tomorrow pm", "tomorrow night")]
TomorrowEvening
};
我从一个可以拥有datetimeV2的LUIS意图调用我的CallForm,如下所示:
[LuisIntent("Call")]
public async Task Call(IDialogContext context, LuisResult result)
{
EntityRecommendation entityRecommendation;
if (result.TryFindEntity("builtin.datetimeV2.datetimerange", out entityRecommendation))
{
context.UserData.SetValue<string>(ContextKeys.CallTimeOption, entityRecommendation.Entity);
}
context.UserData.Call(new CallForm(), CallFormResumeAfter);
}
然后我想在CallForm的StartAsync中预先填充它但不知道如何......
public async Task StartAsync(IDialogContext context)
{
var state = new CallTimeForm();
string calltime;
if(context.UserData.TryGetValue(ContextKeys.CallTimeOption, out calltime))
{
state.PreferredCallTime = -- is there a way to match calltime with CallTimeOptions ? --
}
var form = new FormDialog<CallTimeForm>(
state,
BuildForm,
FormOptions.PromptInStart);
context.Call(form, this.AfterBuildForm);
}
答案 0 :(得分:1)
如何执行此操作的示例是通过反射和Attribute.GetCustomAttribute
检索应用于的指定类型的自定义属性 程序集,模块,类型成员或方法参数。
扩展方法
public static class EnumEx
{
public static T GetValueFromTerms<T>(string value)
{
var type = typeof(T);
if (!type.IsEnum)
{
throw new InvalidOperationException();
}
foreach (var field in type.GetFields())
{
if (Attribute.GetCustomAttribute(field, typeof(TermsAttribute)) is TermsAttribute attribute)
{
// Search your attribute array or properties here
// Depending on the structure of your attribute
// you will need to change this if Conidition
if (attribute.ContainsTerms(value))
{
return (T)field.GetValue(null);
}
}
else
{
if (field.Name == value)
{
return (T)field.GetValue(null);
}
}
}
throw new ArgumentException("Not found.", nameof(value));
// or return default(T);
}
}
用法
var callTimeOptions = EnumEx.GetValueFromTerms<CallTimeOptions>("tomorrow noon time");
但是,我认为你不会以正确的方式解决这个问题。
更具前瞻性的系统是使用Dictionary<string,CallTimeOptions>
查找搜索字词并将其映射到枚举。
我知道属性看起来很整洁,如果你想扩展这么多可能会运行良好,但是字典可以从db或file加载,而且可能更容易维护(取决于你的要求)