Вот макрос, который я использую для этой цели. Он будет генерировать конструктор из полей и свойств, имеющих частный сеттер.
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100
Imports System.Diagnostics
Imports System.Collections.Generic
Public Module Temp
Sub AddConstructorFromFields()
DTE.UndoContext.Open("Add constructor from fields")
Dim classElement As CodeClass, index As Integer
GetClassAndInsertionIndex(classElement, index)
Dim constructor As CodeFunction
constructor = classElement.AddFunction(classElement.Name, vsCMFunction.vsCMFunctionConstructor, vsCMTypeRef.vsCMTypeRefVoid, index, vsCMAccess.vsCMAccessPublic)
Dim visitedNames As New Dictionary(Of String, String)
Dim element As CodeElement, parameterPosition As Integer, isFirst As Boolean = True
For Each element In classElement.Children
Dim fieldType As String
Dim fieldName As String
Dim parameterName As String
Select Case element.Kind
Case vsCMElement.vsCMElementVariable
Dim field As CodeVariable = CType(element, CodeVariable)
fieldType = field.Type.AsString
fieldName = field.Name
parameterName = field.Name.TrimStart("_".ToCharArray())
Case vsCMElement.vsCMElementProperty
Dim field As CodeProperty = CType(element, CodeProperty)
If field.Setter.Access = vsCMAccess.vsCMAccessPrivate Then
fieldType = field.Type.AsString
fieldName = field.Name
parameterName = field.Name.Substring(0, 1).ToLower() + field.Name.Substring(1)
End If
End Select
If Not String.IsNullOrEmpty(parameterName) And Not visitedNames.ContainsKey(parameterName) Then
visitedNames.Add(parameterName, parameterName)
constructor.AddParameter(parameterName, fieldType, parameterPosition)
Dim endPoint As EditPoint
endPoint = constructor.EndPoint.CreateEditPoint()
endPoint.LineUp()
endPoint.EndOfLine()
If Not isFirst Then
endPoint.Insert(Environment.NewLine)
Else
isFirst = False
End If
endPoint.Insert(String.Format(MemberAssignmentFormat(constructor.Language), fieldName, parameterName))
parameterPosition = parameterPosition + 1
End If
Next
DTE.UndoContext.Close()
Try
' This command fails sometimes '
DTE.ExecuteCommand("Edit.FormatDocument")
Catch ex As Exception
End Try
End Sub
Private Sub GetClassAndInsertionIndex(ByRef classElement As CodeClass, ByRef index As Integer, Optional ByVal useStartIndex As Boolean = False)
Dim selection As TextSelection
selection = CType(DTE.ActiveDocument.Selection, TextSelection)
classElement = CType(selection.ActivePoint.CodeElement(vsCMElement.vsCMElementClass), CodeClass)
Dim childElement As CodeElement
index = 0
For Each childElement In classElement.Children
Dim childOffset As Integer
childOffset = childElement.GetStartPoint(vsCMPart.vsCMPartWholeWithAttributes).AbsoluteCharOffset
If selection.ActivePoint.AbsoluteCharOffset < childOffset Or useStartIndex Then
Exit For
End If
index = index + 1
Next
End Sub
Private ReadOnly Property MemberAssignmentFormat(ByVal language As String) As String
Get
Select Case language
Case CodeModelLanguageConstants.vsCMLanguageCSharp
Return "this.{0} = {1};"
Case CodeModelLanguageConstants.vsCMLanguageVB
Return "Me.{0} = {1}"
Case Else
Return ""
End Select
End Get
End Property
End Module
Неправильное использование оценка открывает Ваш код для инжекционных нападений
, Отладка может быть более сложной (никакие номера строки, и т.д.)
, код eval'd выполняется медленнее (никакая возможность компилировать/кэшировать код eval'd)
Редактирование: Как @Jeff Walden указывает в комментариях, № 3 менее верен сегодня, чем это было в 2008. Однако, в то время как некоторое кэширование скомпилированных сценариев может произойти, это будет только ограничено сценариями, которые являются eval'd, повторенным без модификации. Более вероятный сценарий - то, что Вы - eval'ing сценарии, которые подверглись небольшой модификации, каждый раз и как таковой не мог кэшироваться. Позвольте нам просто сказать, что НЕКОТОРЫЙ код eval'd выполняется более медленно.
Это может стать большим количеством проблемы, поскольку следующее поколение браузеров выпускает некоторую разновидность компилятора JavaScript. Код, выполненный через Оценку, не может работать, а также остальная часть Вашего JavaScript против этих более новых браузеров. Кто-то должен сделать некоторое профилирование.
Помимо возможных проблем безопасности, если Вы выполняете отправленный пользователями код, большую часть времени существует лучший путь, который не включает перепарсинг кода каждый раз, когда это выполняется. Анонимные функции или свойства объектов могут заменить большую часть использования оценки и намного более безопасны и быстрее.
Это значительно снижает Ваш уровень уверенности о безопасности.
Это не обязательно, что плохо, если Вы знаете, в каком контексте Вы используете его.
, Если Ваше приложение использует eval()
для создания объекта из некоторого JSON, который возвратился из XMLHttpRequest к собственному сайту, созданному доверяемым серверным кодом, это - вероятно, не проблема.
Недоверяемый клиентский код JavaScript не может сделать так многого так или иначе. Если вещь, на которой Вы выполняетесь eval()
, прибыла из разумного источника, Вы в порядке.
Если Вы не на 100% уверены, что оцениваемый код от надежного источника (обычно Ваше собственное приложение) тогда, это - безошибочный способ представить Вашу систему атаке с использованием кросс-сайтовых сценариев.
Если Вы не позволяете оценке () динамический контент (через cgi или вводите), это так же безопасно и твердо как весь другой JavaScript на Вашей странице.
Одна вещь иметь в виду состоит в том, что можно часто использовать оценку () для выполнения кода в иначе ограниченной среде - сайты социальных сетей, что блок, определенные функции JavaScript можно иногда дурачить путем разбивания их в блоке оценки -
eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');
Поэтому, если Вы надеетесь выполнять некоторый код JavaScript, где это не могло бы иначе быть позволено ( Myspace, я смотрю на Вас...) тогда оценка () может быть полезным приемом.
Однако по всем упомянутым выше причинам, Вы не должны использовать его для своего собственного кода, где Вы имеете полный контроль - это просто не необходимо, и богатое пониженный к 'хитрой полке' взломов JavaScript.
оценка является не всегда злом. Существуют времена, где это является совершенно соответствующим.
Однако оценка в настоящее время и исторически в широком масштабе злоупотребляется людьми, которые не знают то, что они делают. Это включает людей, пишущих учебные руководства JavaScript, к сожалению, и в некоторых случаях это может действительно иметь последствия безопасности - или, чаще, простые ошибки. Так, чем больше мы можем сделать для броска вопросительного знака по оценке, тем лучше. Любое время Вы используете оценку, Вам нужно к проверке работоспособности, что Вы делаете, потому что возможности - Вы, могло делать его лучший, более безопасный, более чистый путь.
, Чтобы дать слишком типичный пример, выбрать цвет элемента с идентификатором, сохраненным в переменном 'картофеле':
eval('document.' + potato + '.style.color = "red"');
, Если авторы вида кода выше подсказка об основах того, как JavaScript возражает работе, они поймут, что квадратные скобки могут использоваться вместо литеральных точечных имен, устраняя потребность в оценке:
document[potato].style.color = 'red';
..., который намного легче считать, а также менее потенциально ошибочный.
(Но тогда, кто-то, который/really/знал то, что они делали, скажет:
document.getElementById(potato).style.color = 'red';
, который более надежен, чем изворотливый старый прием доступа к элементам DOM прямо из объекта документа.)
Это - вообще только проблема при передаче ввода данных пользователем оценки.
Передающий ввод данных пользователем к оценке () является угрозой безопасности, но также и каждый вызов оценки () создает новый экземпляр интерпретатора JavaScript. Это может быть пожирателем ресурсов.
Главным образом намного более трудно поддержать и отладить. Это похоже goto
. Можно использовать его, но это делает его тяжелее для нахождения проблем и тяжелее на людях, которые, возможно, должны внести изменения позже.
Я полагаю, что это - потому что это может выполнить любую функцию JavaScript от строки. Используя его облегчает для людей вводить код жулика в приложение.
Две точки приходят на ум:
безопасность (но, пока Вы генерируете строку, которая будет оценена сами, это могло бы быть надуманным вопросом)
Производительность: пока код, который будет выполняться, не неизвестен, он не может быть оптимизирован. (о JavaScript и производительности, конечно представление Steve Yegge )
Это - возможная угроза безопасности, это имеет различный объем выполнения и довольно неэффективно, поскольку это создает совершенно новую среду сценариев для выполнения кода. Посмотрите здесь еще для некоторой информации: оценка .
Это довольно полезно, тем не менее, и используемый с модерированием может добавить большую хорошую функциональность.
Сборка "мусора"
сборка "мусора" браузеров понятия не имеет, может ли код, это - eval'ed, быть удален из памяти, таким образом, это просто сохраняет сохраненным, пока страница не перезагружается. Не слишком плохо, если Ваши пользователи находятся только на Вашей странице вскоре, но это может быть проблема для веб-приложения.
Вот сценарий для демонстрации проблемы
https://jsfiddle.net/CynderRnAsh/qux1osnw /
document.getElementById("evalLeak").onclick = (e) => {
for(let x = 0; x < 100; x++) {
eval(x.toString());
}
};
Что-то столь же простое, как вышеупомянутый код заставляет небольшой объем памяти быть хранилищем, пока приложение не умирает. Это хуже, когда evaled сценарий является гигантской функцией и обратился к интервалу.
Если вы хотите, чтобы пользователь вводил некоторые логические функции и выполнял операцию И, ИЛИ, тогда функция eval в JavaScript идеально подходит. Я могу принять две строки и eval (uate) string1 === string2
и т. Д.