Swift 4
/// Takes the screenshot of the screen and returns the corresponding image
///
/// - Parameter shouldSave: Boolean flag asking if the image needs to be saved to user's photo library. Default set to 'true'
/// - Returns: (Optional)image captured as a screenshot
open func takeScreenshot(_ shouldSave: Bool = true) -> UIImage? {
var screenshotImage :UIImage?
let layer = UIApplication.shared.keyWindow!.layer
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
guard let context = UIGraphicsGetCurrentContext() else {return nil}
layer.render(in:context)
screenshotImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let image = screenshotImage, shouldSave {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
return screenshotImage
}
Обновлено для Swift 2
Код, который вы предоставляете, работает, но не позволяет вы должны захватить NavigationBar
и StatusBar
на снимке экрана. Если вы хотите сделать снимок экрана вашего устройства, который будет включать в себя NavigationBar
, вы должны использовать следующий код:
func screenShotMethod() {
let layer = UIApplication.sharedApplication().keyWindow!.layer
let scale = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
layer.renderInContext(UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
}
С помощью этого кода:
StatusBar
не будет отображаться. Я полностью согласен с этим сообщением (для тех, кто жалуется на отсутствие ToString, есть атрибут отладчика для предоставить собственный формат для вашего класса).
В верхней части приведенного выше списка я бы также добавил следующие разумные запросы:
T: новый (строка)
, или где T: новый (строка, int)
var e = new Foo (); e {Bar = baz};
Either
», - нет, поэтому мне бы хотелось каким-нибудь способом объявить закрытый алгебраический тип и обеспечить полное сопоставление с образцом на это (в основном первоклассная поддержка шаблона посетителя, но гораздо более эффективная); так что просто возьмите перечисления, расширьте их с помощью исчерпывающей поддержки сопоставления с образцом и не допускайте недопустимых случаев System.IO
, такие как Stream
, несколько плохо спроектированы; любой интерфейс, который требует от некоторых реализаций выброса NotSupportedException
, является плохой конструкцией, IList
должен быть намного проще, чем он есть; на самом деле это может быть верно для многих конкретных интерфейсов коллекций, таких как ICollection
, INotifyPropertyChanged
, которые принимают имя поля в виде строки; вы можете сделать это, используя метод расширения, который принимает лямбда с выражением MemberExpression
, т.е. () => Foo
, но это не очень эффективно,
nameof ()
для имен отдельных элементов, но он не работает в универсальных шаблонах ( nameof (T) == "T"
вместо фактическое имя аргумента типа: вам все равно нужно выполнить typeof (T) .Name
)) - и это не позволит вам получить строку «путь», например nameof (this.ComplexProperty. Value) == "Value"
, ограничивающее его возможные приложения. IArithmetic
; также возможны другие полезные общие интерфейсы операторов readonly
, а в C # 6.0 добавлены автоматические свойства только для чтения, хотя это не так строго, как настоящая языковая поддержка неизменяемых типов и значений. Полагаю, на данный момент этого достаточно. Это все раздражения, с которыми я столкнулся на прошлой неделе. Я, вероятно, мог бы продолжать в течение нескольких часов, если бы действительно задумался. C # 4.0 уже добавляет именованные, необязательные аргументы и аргументы по умолчанию, что я решительно одобряю.
Теперь для одного необоснованного запроса:
Довольно, пожалуйста? : -)
Редактирование
5. Другое мое раздражение то, как Система. Отражение. BindingFlags, имеет различное использование в зависимости от метода Ваше использование. В FindFields, например, что имеют в виду CreateInstance или SetField? Это - случай, где они перегрузили значение позади этого перечисления, которое сбивает с толку.
Я действительно удивлен, что я первый для упоминания этого:
введенные наборы данных ADO.NET не представляют nullable столбцы как свойства nullable типов. Необходимо быть в состоянии записать это:
int? i = myRec.Field;
myRec.Field = null;
Вместо этого необходимо записать это, которое просто глупо:
int? i = (int?)myRec.IsFieldNull() ? (int?)null : myRec.Field;
myRec.SetFieldNull();
Это было раздражающим в.NET 2.0, и это является еще более раздражающим теперь, когда необходимо использовать возню как вышеупомянутое в хороших аккуратных запросах LINQ.
Это является также раздражающим, что сгенерированный Add<TableName>Row
метод столь же нечувствителен к понятию nullable типов. Тем более поэтому начиная со сгенерированного TableAdapter
методы не.
нет много в.NET, которая заставляет меня чувствовать, что команда разработчиков заявила "Хорошо, мальчики, мы достаточно близки - поставляют его!" Но это уверенное делает.
Я не понимаю, что Вы не можете сделать
где T: новый (U)
, Таким образом, Вы объявляете, что универсальный тип T имеет конструктора не по умолчанию.
редактирование:
я хочу сделать это:
public class A
{
public A(string text)
{
}
}
public class Gen<T> where T : new(string text)
{
}
Маленькое домашнее животное C# peev - конструкторы использует C++ / синтаксис Java наличия конструктора быть тем же именем как класс.
New()
или ctor()
было бы намного более хорошим.
И уверенный, инструменты, такие как coderush делают это меньшим количеством проблемы для переименования классов, но от удобочитаемости POV, Новый (), обеспечивает большую ясность.
Reset()
метод на IEnumerator<T>
был ошибкой (для блоков итератора, спецификация языка даже требования , что это выдает исключение) IEnumerable[<T>]
ApplicationException
, скорее впал в немилость - который был ошибкой? Contains
, тогда Add
), таким образом, набор, который синхронизирует отличные операции, не является всем, чем полезный using
/ lock
шаблон - возможно, разрешение им совместно использовать допускающее повторное использование (расширяемый?) синтаксис; можно моделировать это путем возврата IDisposable
и использования using
, но это, возможно, было более ясно throw
) был бы хорош (контраст по отношению к [1 112] и т.д.) foreach
расширение, означая, что anon-methods/lambdas получают единственную переменную, а не один на повторение (болезненный с поточной обработкой/асинхронной/и т.д.) TextWriter основа класс StreamWriter. wtf?
, Который всегда смущает меня до крайности.
Переменные с неявно определенным типом были реализованы плохо IMO. Я знаю, что необходимо действительно только использовать их при работе с выражениями Linq, но это является раздражающим, что Вы не можете объявить их за пределами локального объема.
Из MSDN:
причина я думаю, что это - плохая реализация, то, что они называют его var, но это - длинный путь от того, чтобы быть вариантом. Это - действительно просто синтаксис стенографии для того, чтобы не иметь необходимость ввести полностью имя класса (кроме тех случаев, когда используемый с Linq)
Одна вещь, которая убрала галочку во мне в 1.x, состояла в том, когда использование эти System.Xml.XmlValidatingReader
, ValidationEventHandler
ValidationEventArgs
не представляет лежание в основе XmlSchemaException
(отметил внутренний), который имеет всю полезную информацию как linenumber
и position
. Вместо этого Вы, как ожидают, будете анализировать это из свойства Строки сообщения или использовать отражение для раскапывания его. Не настолько хороший, когда Вы хотите возвратить более санированную ошибку конечному пользователю.
.Parameters. Добавьте (), метод на SqlCommand в V1 платформы был ужасно разработан - одна из перегрузок в основном не работала бы, если бы Вы передали в параметре со значением (интервал) 0 - ведомый к ним создающий.Parameters. AddWithValue () метод на классе SqlCommand.
Быть в состоянии вызвать дополнительный метод на пустую переменную является спорным, например,
объект a=null; a. MyExtMethod ();//это является вызываемым, примите где-нибудь, что это определило MyExtMethod
, Это могло быть удобно, но это неоднозначно по темам исключения нулевой ссылки.
Одно именование 'дефект'. 'C' "конфигурации" в System.configuration.dll должен капитализироваться.
Обработка исключений. Исключение должно быть насильственно поймано или выдано как в Java, компилятор должен проверить его во время компиляции. Пользователи не должны полагаться на комментарии для получения информации об исключениях в рамках целевого вызова.
Microsoft не исправит очевидные ошибки в платформе и не обеспечит рычаги, таким образом, конечные пользователи смогут зафиксировать их.
кроме того, нет никакого пути к исполняемым файлам.NET двоичного патча во времени выполнения и никакого способа определить частные версии библиотек платформы.NET без двоичного файла, исправляющего собственные библиотеки (для прерывания вызова загрузки), и ILDASM не является распространяемым файлом, таким образом, я не могу автоматизировать патч так или иначе.
Дополнительные методы хороши, но они - ужасный способ решить проблемы, которые, возможно, были решены инструмент для очистки с реальным mixins (взгляд на рубин для наблюдения то, что я говорю о), на предмет mixins. Действительно хороший способ добавить их к языку состоял бы в том, чтобы позволить дженерикам использоваться для наследования. Это позволяет Вам расширять существующие классы хорошим объектно-ориентированным способом:
public class MyMixin<T> : T
{
// etc...
}
это может использоваться как это для расширения строки, например:
var newMixin = new MyMixin<string>();
Это намного более мощно, чем дополнительные методы, потому что это позволяет Вам переопределенным методам, например, обертывать их позволяющий подобную AOP функциональность в языке.
Извините за напыщенную речь:-)
Путем мы используем свойства, иногда раздражает меня. Мне нравится думать о них как об эквиваленте getFoo Java () и setFoo () методы. Но они не.
, Если Инструкции по Использованию Свойства состояние, что свойства должны быть в состоянии быть установленными в любом порядке так сериализация, может работать, тогда они бесполезны для разовой методом set проверки. Если Вы происходите из среды, где Вам нравится препятствовать объекту позволить себе когда-либо входить в недопустимое состояние, то свойства не являются Вашим решением. Иногда мне не удается видеть, как они лучше, чем общедоступные участники, так как мы так ограничены в том, какие виды вещей мы , предположил делать в свойствах.
С этой целью, я всегда отчасти желал (это главным образом думает вслух здесь, я просто вид желания, я мог сделать что-то вроде этого), что я мог расширить синтаксис свойства так или иначе. Вообразите что-то вроде этого:
private string password;
public string Password
{
// Called when being set by a deserializer or a persistence
// framework
deserialize
{
// I could put some backward-compat hacks in here. Like
// weak passwords are grandfathered in without blowing up
this.password = value;
}
get
{
if (Thread.CurrentPrincipal.IsInRole("Administrator"))
{
return this.password;
}
else
{
throw new PermissionException();
}
}
set
{
if (MeetsPasswordRequirements(value))
{
throw new BlahException();
}
this.password = value;
}
serialize
{
return this.password;
}
}
я не уверен, полезно ли это или на что это получающий доступ те были бы похожи. Но мне просто жаль, что я не мог сделать больше со свойствами и действительно рассматривать их, любят, добираются и методы установки.
Уже добавить к длинному списку правильных замечаний, сделанных другими:
DateTime.Now == DateTime.Now
в большинстве, но не всех случаях.
String
то, которое неизменно, имеет набор опций для конструкции и управления, но StringBuilder
(который изменяем), не делает.
Monitor.Enter
и Monitor.Exit
должны были быть методы экземпляра, таким образом, вместо newing конкретный объект для блокировки, Вы могли новый Monitor
и соединять это.
Деструкторы никогда нельзя было называть деструкторами. Спецификация ECMA называет их финализаторами, который намного менее сбивает с толку толпу C++, но спецификация языка все еще называет их деструкторами.
0 слабого освещения улиц как перечисление
особенности перечисления: http://blogs.msdn.com/abhinaba/archive/2007/01/09/more-peculiarites-of-enum.aspx
, как проиллюстрировано этим хорошим примером: http://plus.kaist.ac.kr/~shoh/postgresql/Npgsql/apidocs/Npgsql.NpgsqlParameterCollection.Add_overload_3.html
мое предложение, помещенное, подают знак хорошему использованию:
вместо:
, если ((myVar & MyEnumName. ColorRed)! = 0)
использование это:
, если ((myVar & MyEnumName. ColorRed)! = @0)
Некоторые классы реализуют интерфейсы, но они не реализуют многие методы того интерфейса, например, Массив реализует IList, но 4 из 9 методов бросают NotSupportedException http://msdn.microsoft.com/en-us/library/system.array_members.aspx
Система. Объект класс:
Равняется и GetHashCode - не, все классы сопоставимы или hashable, должен быть перемещен в интерфейс. IEquatable или IComparable (или подобный) приходят на ум.
ToString - не все классы могут быть преобразованы в строку, должен быть перемещен в интерфейс. IFormattable (или подобный) приходит на ум.
ICollection. Свойство SyncRoot:
Дженерики должны были быть там с начала:
Ужасное (и довольно невидимый для большинства людей) O (N^2) поведение вложенных/рекурсивных итераторы .
я вполне разрушен, что они знают об этом, знают , как зафиксировать его , но это не просматривается как наличие достаточного приоритета заслужить включение.
я работаю с деревом как структуры все время и имею для исправления кода в других отношениях умных людей, когда они непреднамеренно представляют очень дорогие операции таким образом.
красота "урожая foreach' состоит в том, что более простой, более легкий синтаксис поощряет корректный, производительный код. Это "яма успеха" , что я думаю, что они должны стремиться к прежде, чем добавить новые опции для долгосрочного успеха платформы.
События в C#, где Вы имеете к явной проверке на слушателей. Разве это не было точкой с событиями, для широковещательной передачи тому, кто бы ни, оказывается, там? Даже если нет никого?
Мы знаем так много о право методы OO. Разъединение, программирование согласно контракту, предотвращение неподходящего наследования, соответствующего использования исключений, открываются/закрывают принципал, замещаемость Liskov, и так далее. Любой все же.Net платформы не используют лучшие практики.
мне единственный самый большой дефект в дизайне.Net не стоит на плечах гигантов; продвижение меньше, чем идеальные парадигмы программирования к массам программистов, которые используют их платформы .
, Если MS обратил внимание на это, мир разработки программного обеспечения, возможно, сделал большие прыжки с точки зрения качества, устойчивости и масштабируемости в это десятилетие, но увы, это, кажется, регрессирует.
Мне не нравится оператор переключения C#.
я хотел бы что-то вроде этого
switch (a) {
1 : do_something;
2 : do_something_else;
3,4 : do_something_different;
else : do_something_weird;
}
Так больше повреждений (легкий забыть) и возможность к отдельным от запятой различным значениям.
Некоторым людям (независимые поставщики программного обеспечения) жаль, что Вы не могли скомпилировать его в машинный код во время изготовления, и связывать его, для создания собственного исполняемого файла, которому не нужно dotNet время выполнения.
Одна из вещей, которая раздражает меня, Predicate<T> != Func<T, bool>
парадокс. Они - оба делегаты типа T -> bool
, и все же они не совместимое присвоение.
Статические участники и вложенные типы в интерфейсах.
Это особенно полезно, когда у интерфейсного участника есть параметр типа, который характерен для интерфейса (, например, enum
). Было бы хорошо вложить перечислимый тип в интерфейсном типе.
Я не знаю, что пошел бы, до для высказывания это - недостаток дизайна, но было бы действительно хорошо, если Вы могли бы вывести лямбда-выражение таким же образом, Вы можете в VB:
VB:
Dim a = Function(x) x * (x - 1)
C#
было бы хорошо, если мог сделать это:
var a = x => x * (x - 1);
Вместо того, чтобы иметь необходимость сделать это:
Func<int, int> a = x => x * (x - 1);
я понимаю, что это не намного более длинно, но в Коде Играют в гольф каждый счетчики символов damnit! Разве они не принимают это во внимание, когда они разрабатывают эти языки программирования?:)
Не любите его, что Вы не можете использовать значения одного перечисления в другом перечислении, например:
enum Colors { white, blue, green, red, black, yellow }
enum SpecialColors { Colors.blue, Colors.red, Colors.Yellow }
Ужасно опасный характер событий по умолчанию. Тот факт, что вы можете вызвать событие и оказаться в несогласованном состоянии из-за удаления подписчиков, просто ужасен. См. отличные статьи Джона Скита и Эрика Липперта для получения дополнительной информации по этой теме.
null
везде.
const
нигде.
API непоследовательны, например, мутирование массива возвращает void
, но добавление к StringBuffer
возвращает тот же мутируемый StringBuffer
.
Интерфейсы коллекций несовместимы с неизменяемыми структурами данных, например, Add
в System.Collections.Generic.IList<_>
не может вернуть результат.
Отсутствие структурной типизации, поэтому вы пишете System.Windows.Media.Effects.SamplingMode.Bilinear
вместо просто Bilinear
.
Мутабельный интерфейс IEnumerator
реализован классами, когда он должен быть неизменяемым struct
.
Равенство и сравнение - полная неразбериха: у вас есть System.IComparable
и Equals
, но также есть System.IComparable<_>
, System.IEquatable
, System.Collections. IComparer
, System.Collections.IStructuralComparable
, System.Collections.IStructuralEquatable
, System.Collections.Generic.IComparer
and System.Collections.Generic.IEqualityComparer
.
Кортежи должны быть структурами, но структуры излишне препятствуют устранению хвостовых вызовов, поэтому один из самых распространенных и фундаментальных типов данных будет выделяться без необходимости и разрушать масштабируемый параллелизм.
CLR (и поэтому C#) не поддерживает Множественное наследование, и ASP.NET наполнен повреждениями LSP...
Те - мое "избранное"...
я мог, вероятно, найти больше ошибок, но те - те, мне не нравится больше всего...!!: (