Давайте попробуем разобраться с открытым текстом. Тогда мы можем попытаться решить это с помощью зашифрованного текста.
Если под «двоичным кодированным» вы подразумевали двоичное кодирование 5, то да. Дробное кодирование 5 и двоичное кодирование 5 имеют открытый текст x ^ 2 + 1.
Если под «массивом, состоящим из E (1), E (0), E (1)» вы подразумевали 3 шифротекста, которые соответственно расшифровываются до 1, 0 и 1, то нет.
[113 ]Извлечение k-го бита (обозначаемого m_k) числа m из его дробного / целочисленного / двоичного кодирования M (x) = m_ {n-1} x ^ {n-1} + ... + m_k x ^ k + ... + m_0 эквивалентно нахождению функции F такой, что для заданного k и любого m F (M (x)) = m_k в \ ZZ_2 [x ] / (х ^ п + 1). Такую функцию нетривиально найти. Даже если он существует, он может иметь форму многочлена 2 ^ n степени, который слишком глубок для гомоморфной оценки.
Сначала нужно решить сценарий 2, изложенный выше, и успешно извлечь эти отдельные биты. Все остальное - это просто группировка по шифротекстам, что можно легко сделать с помощью rotate_rows
в SEAL.
Я подозреваю, что это - проблема JITting. В настоящее время JIT снова использует тот же сгенерированный код для всех аргументов ссылочного типа - так a List<string>
vtable точки к тому же машинному коду как машинный код List<Stream>
. Это не работало бы если каждый new T()
звоните должен был быть разрешен в коде JITted.
Просто предположение, но это делает определенное количество смысла.
Одна интересная небольшая точка: ни в том, ни в другом случае делает конструктора без параметров типа значения, названы, если существует один (который очень редок). Посмотрите мое недавнее сообщение в блоге для деталей. Я не знаю, существует ли какой-либо способ вызвать его в деревьях выражений.
Это вероятно, потому что не ясно, является ли T типом значения или ссылочным типом. Создание этих двух типов в неуниверсальном сценарии производит совсем другой IL. Перед лицом этой неоднозначности C# вынужден использовать универсальный метод создания типа. Активатор. CreateInstance отвечает всем требованиям.
Быстрое экспериментирование, кажется, поддерживает эту идею. Если Вы введете в следующем коде и исследуете IL, то он будет использовать initobj вместо CreateInstance, потому что нет никакой неоднозначности на типе.
static void Create<T>()
where T : struct
{
var x = new T();
Console.WriteLine(x.ToString());
}
Переключение его к классу и новый () ограничение, хотя все еще вызывает Активатор. CreateInstance.
Интересное наблюдение :)
Вот более простая вариация на Ваше решение:
static T Create<T>() where T : new()
{
Expression<Func<T>> e = () => new T();
return e.Compile()();
}
Очевидно наивный (и возможный медленный) :)
Зачем нужен этот обходной путь?
Потому что общее ограничение new () было добавлено в C # 2.0 в .NET 2.0.
Expression
Итак, ваш обходной путь необходим, потому что это было невозможно в .NET 2.0. Между тем, (1) использование Activator.CreateInstance () было возможно, и (2) в IL отсутствует способ реализации 'new T ()', поэтому Activator.CreateInstance () использовался для реализации этого поведения.
Это немного быстрее, поскольку выражение компилируется только один раз:
public class Foo<T> where T : new()
{
static Expression<Func<T>> x = () => new T();
static Func<T> f = x.Compile();
public static T build()
{
return f();
}
}
Анализируя производительность, этот метод работает так же быстро, как и более подробный скомпилированный выражение и намного, намного быстрее, чем new T ()
(в 160 раз быстрее на моем тестовом ПК).
Для немного лучшей производительности вызов метода сборки может быть исключен, а функтор может быть возвращен вместо этого, который клиент может кэшировать и вызывать напрямую.
public static Func<T> BuildFn { get { return f; } }