Остановка всех ботов была бы довольно трудной, особенно не используя КАПЧУ. Я думаю, что необходимо приблизиться к этому с точки зрения реализации большого разнообразия мер для создания жизни тяжелее для сценаристов.
я полагаю, что это - одна мера, которая избавилась бы от некоторых из них:
Вы могли попробовать рандомизация идентификаторов и имен классов из Ваших тегов с каждым ответом. Это вынудило бы ботов полагаться на положение и контекст важных тегов, который требует более сложного бота. Кроме того, Вы могли рандомизировать положение тегов, если Вы хотите использовать относительное или абсолютное расположение в свой CSS.
самый большой недостаток с этим подходом состоит в том, что необходимо было бы предпринять шаги, чтобы гарантировать, что файл CSS не кэшируется клиентский, потому что он должен был бы, конечно, содержать рандомизированные идентификаторы & имена классов. Один способ преодолеть это не состоит в том, чтобы использовать внешние файлы CSS и вместо этого помещать CSS с рандомизированными селекторами в <head></head>
раздел страницы. Это позволило бы рандомизированному CSS быть клиентский кэшируемый наряду с остальной частью страницы.
Если синтаксис не соответствует нормальному шаблону, измените синтаксис. Как насчет:
public void MyFunction(params KeyValuePair<string, object>[] pairs)
{
// ...
}
public static class Pairing
{
public static KeyValuePair<string, object> Of(string key, object value)
{
return new KeyValuePair<string, object>(key, value);
}
}
Использование:
MyFunction(Pairing.Of("Key1", 5), Pairing.Of("Key2", someObject));
Еще более интересным было бы добавить метод расширения к строке
, чтобы сделать его сопоставляемым:
public static KeyValuePair<string, object> PairedWith(this string key, object value)
{
return new KeyValuePair<string, object>(key, value);
}
Использование:
MyFunction("Key1".PairedWith(5), "Key2".PairedWith(someObject));
Изменить : Вы также можете используйте синтаксис словаря без общих скобок, производный от Dictionary <,>
:
public void MyFunction(MessageArgs args)
{
// ...
}
public class MessageArgs : Dictionary<string, object>
{}
Использование:
MyFunction(new MessageArgs { { "Key1", 5 }, { "Key2", someObject } });
Используйте Словарь ...
void Main()
{
var dic = new Dictionary<string, object>();
dic.Add( "Key1", 1 );
dic.Add( "Key2", 2 );
MyFunction( dic ).Dump();
}
public static object MyFunction( IDictionary dic )
{
return dic["Key1"];
}
Вот то же самое:
static void Main(string[] args)
{
// http://msdn.microsoft.com/en-us/library/bb531208.aspx
MyMethod(new Dictionary<string,string>()
{
{"key1","value1"},
{"key2","value2"}
});
}
static void MyMethod(Dictionary<string, string> dictionary)
{
foreach (string key in dictionary.Keys)
{
Console.WriteLine("{0} - {1}", key, dictionary[key]);
}
}
Некоторые подробности по инициализации словаря можно найти здесь .
Использование словаря:
myFunction(new Dictionary<string, object>(){
{"Key", value},
{"Key2", value}});
То есть вам нужен только один новый словарь
, а не для каждого аргумента. Получить ключи и значения тривиально.
Или с анонимным типом:
myFunction(new {
Key = value,
Key2 = value});
Что не очень удобно использовать внутри функции, вам понадобится отражение. Это выглядело бы примерно так:
foreach (PropertyInfo property in arg.GetType().GetProperties())
{
key = property.Name;
value = property.GetValue(arg, null);
}
(Прямо из головы, наверное, какие-то ошибки ...)
Забавно, я только что создал (несколько минут назад) метод, который позволяет делать это, используя анонимные типы и отражение:
MyMethod(new { Key1 = "value1", Key2 = "value2" });
public void MyMethod(object keyValuePairs)
{
var dic = DictionaryFromAnonymousObject(keyValuePairs);
// Do something with the dictionary
}
public static IDictionary<string, string> DictionaryFromAnonymousObject(object o)
{
IDictionary<string, string> dic = new Dictionary<string, string>();
var properties = o.GetType().GetProperties();
foreach (PropertyInfo prop in properties)
{
dic.Add(prop.Name, prop.GetValue(o, null) as string);
}
return dic;
}
Это немного похоже на взлом, но вы можете сделать так, чтобы ваш класс Message
реализовал интерфейс IEnumerable
и дал ему метод Add
. После этого вы сможете использовать синтаксис инициализатора коллекции:
Agent.SendMessage
(
new Message(MessageTypes.SomethingHappened) {{ "foo", 42 }, { "bar", 123 }}
);
// ...
public class Message : IEnumerable
{
private Dictionary<string, object> _map = new Dictionary<string, object>();
public Message(MessageTypes mt)
{
// ...
}
public void Add(string key, object value)
{
_map.Add(key, value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_map).GetEnumerator();
// or throw a NotImplementedException if you prefer
}
}