QueryEngine<T0>.AddOperatorHandler
Declaration
public void AddOperatorHandler(string op, Func<TFilterVariable,TFilterConstant,bool> handler);public void AddOperatorHandler(string op, Func<TFilterVariable,TFilterConstant,stringComparison,bool> handler);Параметры
| Параметр | Описание |
|---|---|
| на | Оператор фильтра. |
| обработчик | Обратный вызов для обработки операции. Принимает TFilterVariable (значение, возвращаемое обработчиком фильтров, оно будет различаться для каждого элемента), TFilterConstant (правое значение оператора, которое является постоянным), и опцию StringComparison и возвращает логическое значение, указывающее, проходит ли фильтр или нет. |
Описание
Добавление пользовательского обработчика оператора фильтра.
<TFilterVariable>: Тип операнда с левой стороны оператора. Это тип, возвращаемый обработчиком фильтров.
<TFilterConstant>: Тип операнда с правой стороны оператора.
Обработчик операторов — это функция, которая выполняется для определенного оператора (например, "=") с определенными требованиями к типу. Обработчик операторов выбирается по возвращаемому значению обработчика фильтров (см. AddFilter), который определяется при анализе запроса, и тип значения фильтра.
Эта функция может быть использована для добавления обработчиков операторов к новому пользовательскому оператору (см. AddOperator для полного примера):
// Add a new operator token const string op = "%"; queryEngine.AddOperator(op); // Define what this operator does, and which types it operates on. queryEngine.AddOperatorHandler(op, (int ev, int fv) => ev % fv == 0);
Но он также может быть использован для регистрации новых обработчиков операторов на существующих операторах:
using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEditor.Search; using UnityEngine; static class Example_QueryEngine_AddOperatorHandler { static List<MyObjectType> s_Data; [MenuItem("Examples/QueryEngine/AddOperatorHandler")] public static void RunExample() { // Set up the query engine var queryEngine = new QueryEngine<MyObjectType>(); queryEngine.AddFilter("id", myObj => myObj.id); queryEngine.AddFilter("prop", myObj => myObj.property); queryEngine.SetSearchDataCallback(myObj => new[] { myObj.id.ToString(), myObj.name }); // Set the global string comparison options (default is OrdinalIgnoreCase) queryEngine.SetGlobalStringComparisonOptions(StringComparison.Ordinal); // Define new handlers for existing operators, but with new types queryEngine.AddOperatorHandler("=", (Property ev, int fv) => HandleIntType(ev, fv, (propValue, filterValue) => propValue == filterValue)); queryEngine.AddOperatorHandler("!=", (Property ev, int fv) => HandleIntType(ev, fv, (propValue, filterValue) => propValue != filterValue)); queryEngine.AddOperatorHandler("<", (Property ev, int fv) => HandleIntType(ev, fv, (propValue, filterValue) => propValue < filterValue)); queryEngine.AddOperatorHandler(">", (Property ev, int fv) => HandleIntType(ev, fv, (propValue, filterValue) => propValue > filterValue)); queryEngine.AddOperatorHandler("<=", (Property ev, int fv) => HandleIntType(ev, fv, (propValue, filterValue) => propValue <= filterValue)); queryEngine.AddOperatorHandler(">=", (Property ev, int fv) => HandleIntType(ev, fv, (propValue, filterValue) => propValue >= filterValue)); // New handlers with support for the global string comparison options queryEngine.AddOperatorHandler(":", (Property ev, string fv, StringComparison options) => HandleStringType(ev, fv, (propValue, filterValue) => propValue.IndexOf(filterValue, options) >= 0)); queryEngine.AddOperatorHandler("=", (Property ev, string fv, StringComparison options) => HandleStringType(ev, fv, (propValue, filterValue) => propValue.Equals(filterValue, options))); queryEngine.AddOperatorHandler("!=", (Property ev, string fv, StringComparison options) => HandleStringType(ev, fv, (propValue, filterValue) => !propValue.Equals(filterValue, options))); s_Data = new List<MyObjectType>() { new MyObjectType { id = 0, property = new Property("size", PropertyType.Integer, 64) }, new MyObjectType { id = 1, property = new Property("size", PropertyType.Integer, 128) }, new MyObjectType { id = 2, property = new Property("tag", PropertyType.String, "item") }, new MyObjectType { id = 3, property = new Property("tag", PropertyType.String, "car item") }, new MyObjectType { id = 3, property = new Property("tag", PropertyType.String, "42") } }; // Find all items that have a property with an integer value < 100 var query = queryEngine.ParseQuery("prop<100"); var filteredData = query.Apply(s_Data).ToList(); Debug.Assert(filteredData.Count == 1, $"There should be 1 item in the filtered list but found {filteredData.Count} items."); Debug.Assert(filteredData.Contains(s_Data[0]), "Test 1 should be in the list as its property value is < 100."); // Find all items that have a property with a string value that contains "Item". // In this case, since the comparison option is Ordinal, we test the casing. query = queryEngine.ParseQuery("prop:Item"); filteredData = query.Apply(s_Data).ToList(); Debug.Assert(filteredData.Count == 0, $"There should be 0 item in the filtered list but found {filteredData.Count} items."); } static bool HandleIntType(Property prop, int value, Func<int, int, bool> operatorHandler) { if (prop.type != PropertyType.Integer) return false; if (!(prop.value is int i)) return false; return operatorHandler(i, value); } static bool HandleStringType(Property prop, string value, Func<string, string, bool> operatorHandler) { if (prop.type != PropertyType.String) return false; if (!(prop.value is string s)) return false; return operatorHandler(s, value); } enum PropertyType { Integer, String } struct Property { public string name { get; } public PropertyType type { get; } public object value { get; set; } public Property(string name, PropertyType type, object value) { this.name = name; this.type = type; this.value = value; } } class MyObjectType { public int id { get; set; } public string name { get; set; } = string.Empty; public Vector2 position { get; set; } = Vector2.zero; public bool active { get; set; } public Property property { get; set; } public override string ToString() { return $"({id}, {name}, ({position.x}, {position.y}), {active})"; } } }