gpt4 book ai didi

c# - 如何调用通用谓词的集合?

转载 作者:行者123 更新时间:2023-11-30 12:59:05 26 4
gpt4 key购买 nike

我的设置

我有一个存储组件集合的实体类:

public class Entity
{
public Dictionary<Type, IComponent> Components { get; set; }
}

组件是任何实现 IComponent 的类,例如 Position、Orientation 等。

我有一个 Filter 类,它存储条件的集合,这些条件基本上只是谓词:

public class Filter
{
public Dictionary<Type, MulticastDelegate> Conditions;

public Filter()
{
Conditions = new Dictionary<Type, MulticastDelegate>();
}

public void Add<T>(Predicate<T> predicate) where T : class, IComponent
{
Conditions.Add(typeof(T), predicate);
}
}

我的问题

我想要做的是允许创建一个过滤器,该过滤器对不同的组件具有不同的条件(谓词)。我想编写一个方法,为任何其组件都符合条件的实体返回 true。

到目前为止我有什么

public bool IsMatchFor(Entity entity)
{
foreach (IComponent component in entity.Components.Values)
{
if (Conditions.ContainsKey(component.GetType()))
// There is a both a Condition in the Filter and a Component in the Entity that match up based on Type.
// Now check to see if the Condition is satisfied by the Component
{
Type genericPredicate = typeof(Predicate<>);
Type[] typeArgs = { component.GetType() };
Type constructedGenericPredicate = genericPredicate.MakeGenericType(typeArgs);
Predicate<IComponent> predicateInstance = (Predicate<IComponent>)Activator.CreateInstance(constructedGenericPredicate, new object[] { component, Conditions[component.GetType()].Method });

if (!predicateInstance.Invoke(component))
{
return false;
}
}
}

return true;
}

我得到的错误

但是我得到一个错误。基本上我似乎无法构建必要的谓词。有更简单的方法吗?

Test method Tests.Utilities.FilterTests.IsMatchFor_WithASingleConditionThatMatchesEntity_ReturnsTrue threw exception: 
System.MissingMethodException: Constructor on type 'System.Predicate`1[[Tests.TestSupportClasses.ComponentType1, Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found.
Result StackTrace:
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, Object[] args)
at Entropy.Utilities.Filter.IsMatchFor(Entity entity) in c:\git\Entropy\Source\Utilities\Filter.cs:line 54
at Tests.Utilities.FilterTests.IsMatchFor_WithASingleConditionThatMatchesEntity_ReturnsTrue() in c:\git\Entropy\Tests\Utilities\FilterTests.cs:line 128

一个用例来说明为什么这比看起来更复杂

我希望能够编写以下代码:

_filter.Add(typeof(ComponentType1), (Predicate<IComponent>)(new Predicate<ComponentType1>(c => c.BoolProperty)));
Assert.IsTrue(_filter.IsMatchFor(_entities[0]));

基本上,通过使用通用谓词,我可以让编辑器帮助我创建条件。然而,上面的行将在编译时失败,因为 Predicate(Of IComponent) 不是从 Predicate(Of ComponentType1) 继承的,即使 ComponentType1 实现了 IComponent。

最佳答案

看起来您真正需要的是 Dictionary<Type, Predicate<IComponent>>而不是持有MulticastDelegate的一般人:

public Dictionary<Type, Predicate<IComponent>> Conditions;

当以这种方式声明时,您根本不需要使用反射,只需检索 Predicate<IComponent> 即可。从字典中很容易地找到:

public bool IsMatchFor(Entity entity)
{
foreach (IComponent component in entity.Components.Values)
{
Predicate<IComponent> componentPredicate;
if (Conditions.TryGetValue(component.GetType(), out componentPredicate))
{
return componentPredicate(component);
}
}

return false;
}

关于c# - 如何调用通用谓词的集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27211908/

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