Object.keys () Метод Object.keys () возвращает массив собственных перечислимых свойств данного объекта в том же порядке, что и для цикла for ... in (разница заключается в том, что for-in loop также перечисляет свойства в цепочке прототипов).
var arr1 = Object.keys(obj);
Object.values () Метод Object.values () возвращает массив собственных значений перечислимого свойства данного объекта в том же порядке, что и что обеспечивается циклом for for ... in (разница заключается в том, что цикл for-in также перечисляет свойства в цепочке прототипов).
var arr2 = Object.values(obj);
Для получения дополнительной информации см. здесь
Свойство "TODO" и список задач
//TODO: [something]
Добавление этого свойства в ваш код (интервал важен) бросает элемент в список задач, и двойной щелчок по элементу переместит вас в соответствующее место в вашем коде.
.Я не знал об общих методах, которые могли бы помочь избежать перегрузки методами. Ниже приведены перегруженные методы для вывода int и двойных чисел.
private static void printNumbers(int [] intNumbers)
{
foreach(int element in intNumbers)
{
Console.WriteLine(element);
}
}
private static void printNumbers(double[] doubleNumbers)
{
foreach (double element in doubleNumbers)
{
Console.WriteLine(element);
}
}
Общий метод, который помогает иметь один метод для обоих вышеприведенных
private static void printNumbers<E>(E [] Numbers)
{
foreach (E element in Numbers)
{
Console.WriteLine(element);
}
}
Я просто хочу упомянуть (из-за OP Metioning, где t: struct), что один из C # Compiler Gotchas состоит в том, что
where T : Enum
не скомпилируется. Это бросает ошибку «ограничение не может быть специальным классом» System.enum '».
Инициализатор коллекции внутри инициализатора объекта:
MailMessage mail = new MailMessage {
To = { new MailAddress("a@example.com"), new MailAddress("b@example.com") },
Subject = "Password Recovery"
};
Вы можете инициализировать целое дерево в одном выражении.
Я немного опоздал в этом разговоре и хотел бы внести следующий вклад. Это может быть новым для некоторых разработчиков.
public class User
{
public long UserId { get; set; }
public String Name { get; set; }
public String Password { get; set; }
public String Email { get; set; }
}
Обычный способ объявления и инициализации - это конструктор или что-то вроде следующего.
User user = new User();
user.UserId = 1;
user.Name = "myname";
etc
Но я нашел следующий способ инициализации. Я знаю, что разработчикам Visual Basic он понравится, потому что он похож на оператор with, доступный только в VB.NET, но не в C#, который выглядит следующим образом.
User user = new User()
{
UserId = 1,
Name = "myname",
Email = "myemail@domain.com",
Password = "mypassword"
};
Одной из наиболее полезных функций Visual Studio является «Создание идентификатора объекта». Он генерирует идентификатор и «прикрепляется» к объекту, поэтому, где бы вы ни смотрели на объект, вы также увидите идентификатор (независимо от потока).
Во время отладки щелкните правой кнопкой мыши всплывающую подсказку для переменных, и вот она. Она также работает с переменными watched / autos / locals.
Это относится к статическим конструкторам. Это метод статического уничтожения (т.е. очистки ресурсов при выходе из программы).
Сначала о классе:
class StaticDestructor
{
/// <summary>
/// The delegate that is invoked when the destructor is called.
/// </summary>
public delegate void Handler();
private Handler doDestroy;
/// <summary>
/// Creates a new static destructor with the specified delegate to handle the destruction.
/// </summary>
/// <param name="method">The delegate that will handle destruction.</param>
public StaticDestructor(Handler method)
{
doDestroy = method;
}
~StaticDestructor()
{
doDestroy();
}
}
Затем, как член класса, вы хотите, чтобы «статический деструктор» выполнял:
private static readonly StaticDestructor destructor = new StaticDestructor
(
delegate()
{
//Cleanup here
}
);
Теперь он будет вызываться при окончательной сборке мусора. Это полезно, если вам абсолютно необходимо освободить определенные ресурсы.
Быстрая и грязная программа, демонстрирующая следующее поведение:
using System;
namespace TestStaticDestructor
{
class StaticDestructor
{
public delegate void Handler();
private Handler doDestroy;
public StaticDestructor(Handler method)
{
doDestroy = method;
}
~StaticDestructor()
{
doDestroy();
}
}
class SomeClass
{
static SomeClass()
{
Console.WriteLine("Statically constructed!");
}
static readonly StaticDestructor destructor = new StaticDestructor(
delegate()
{
Console.WriteLine("Statically destructed!");
}
);
}
class Program
{
static void Main(string[] args)
{
SomeClass someClass = new SomeClass();
someClass = null;
System.Threading.Thread.Sleep(1000);
}
}
}
Когда программа завершается, вызывается «статический деструктор».
Я не оправдываю это, но я был удивлен, что goto все еще существует утки от входящих снарядов
Не скрытый, но крутой. Я нахожу это более сжатой заменой для простого if-then-else, который просто присваивает значение на основе условия.
string result =
i < 2 ? //question
"less than 2" : //answer
i < 5 ? //question
"less than 5": //answer
i < 10 ? //question
"less than 10": //answer
"something else"; //default answer
Имея дело с взаимодействием между C ++ и C #, многие люди не понимают, что C ++ / CLI - отличный вариант.
Допустим, у вас есть C ++ DLL и C # DLL, которые зависят от C ++ DLL. Часто самый простой способ - скомпилировать некоторые (или все) модули библиотеки DLL C ++ с ключом / clr. Чтобы вызвать C #, библиотека C ++ должна написать управляемые классы-оболочки C ++ в DLL C ++. Классы C ++ / CLI могут вызывать собственный код C ++ гораздо более плавно, чем C #, потому что компилятор C ++ автоматически генерирует P / вызовы для вас, имеет библиотеку специально для взаимодействия, а также языковые функции для взаимодействия, такие как pin_ptr , И это позволяет управляемому и машинному коду сосуществовать в одном двоичном файле.
На стороне C # вы просто вызываете DLL, как и любой другой двоичный код .NET.
Если вы хотите запретить сборщику мусора запускать финализатор объекта, просто используйте GC.SuppressFinalize (object);
. Аналогично, GC.KeepAlive (object);
не позволит сборщику мусора собрать этот объект, ссылаясь на него. Не очень часто используется, по крайней мере, по моему опыту, но полезно знать на всякий случай.
Отражение настолько сильное, когда используется осторожно. Я использовал его в системе шаблонов электронной почты. В диспетчер шаблонов будет передан объект, а в шаблоны html будут встроены поля, которые ссылаются на свойства, которые можно получить из переданного объекта с помощью отражения. Получилось очень красиво.
Фильтры исключений . Итак, «скрытые» вы не можете даже использовать их (по крайней мере, из C #) без патча после компиляции;)
Когда вам необходимо (а) синхронно обмениваться данными между объектами о возникновении события, существует специальный интерфейс, называемый ISynchronizeInvoke .
Цитата из статьи MSDN ( link ):
Объекты, реализующие этот интерфейс, могут получать уведомление о том, что событие произошло, и могут отвечать на запросы о событии. Таким образом, клиенты могут гарантировать, что один запрос был обработан, прежде чем они отправят следующий запрос, который зависит от завершения первого.
Вот общая оболочка:
protected void OnEvent<T>(EventHandler<T> eventHandler, T args) where T : EventArgs
{
if (eventHandler == null) return;
foreach (EventHandler<T> singleEvent in eventHandler.GetInvocationList())
{
if (singleEvent.Target != null && singleEvent.Target is ISynchronizeInvoke)
{
var target = (ISynchronizeInvoke)singleEvent.Target;
if (target.InvokeRequired) {
target.BeginInvoke(singleEvent, new object[] { this, args });
continue;
}
}
singleEvent(this, args);
}
}
и вот пример использования:
public event EventHandler<ProgressEventArgs> ProgressChanged;
private void OnProgressChanged(int processed, int total)
{
OnEvent(ProgressChanged, new ProgressEventArgs(processed, total));
}
Не уверен, что Microsoft понравится этот вопрос, особенно с таким количеством ответов. Я уверен, что однажды я слышал, как глава Microsoft сказал:
скрытая функция - это бесполезная функция
... или что-то в этом роде.
Использование @ перед строкой, содержащей escape-символ. Обычно, когда для присвоения строковой переменной используется физический путь, все используют '\', где в строке присутствует escape-символ.
например string strPath = "D: \ sites \ web1 \ images \";
Но escape-символы можно игнорировать, используя @ перед строковым значением.
например строка strPath = @ "D: \ sites \ web1 \ images \";
Не знайте, является ли это секретом по сути, но я любил добавленное Счетное (добавляет к IEnumerable), класс в Системе. Linq.
http://msdn.microsoft.com/en-us/library/system.linq.enumerable_members.aspx
, В то время как ключевое слово урожая уже перечисляется. Блоки итератора чертовски удивительны. Я использовал их для создания Списков, которые будут протестированы, чтобы видеть, были ли они взаимно-простыми. Это в основном позволяет вам идти, хотя функция, которая возвращает значения один за другим и остановка любое время.
, О, я почти забыл лучший класс в мире, когда вы не можете больше оптимизировать его. BackgroundWorker!!!!
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Другой способ получить IEnumerable через доходность без объяснения причин, создавая IEnumerable объект
public IEnumerable<Request> SomeMethod(IEnumerable<Request> requests)
{
foreach (Request request in requests)
yield return DoSomthing(request);
}
Я не знаю, является ли это скрытой функцией (""). Любая строковая функция.
Этот трюк для вызова частных методов с помощью Delegate.CreateDelegate очень удобен.
var subject = new Subject();
var doSomething = (Func<String, String>)
Delegate.CreateDelegate(typeof(Func<String, String>), subject, "DoSomething");
Console.WriteLine(doSomething("Hello Freggles"));
Большая часть P / Invoke немного странная.
Пример атрибутов:
[DllImport ("gdi32.dll")]
[return : MarshalAs(UnmanagedType.I4)]
[StructLayout(LayoutKind.Sequential)]
Что касается сообщения с постоянной ссылкой « Скрытые возможности C #? », есть еще один способ сделать то же самое - отступы / разрывы строк. Проверьте это ..
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.NewLineOnAttributes = true;
xmlWriterSettings.Indent = true;
XmlWriter xml = XmlWriter.Create(@"C:\file.xml", xmlWriterSettings);
// Start writing the data using xml.WriteStartElement(), xml.WriteElementString(...), xml.WriteEndElement() etc
Я не уверен, что это неизвестная функция!
Разделите статические поля в зависимости от универсального типа окружающего класса.
public class StaticConstrucEx2Outer<T> {
// Will hold a different value depending on the specicified generic type
public T SomeProperty { get; set; }
static StaticConstrucEx2Outer() {
Console.WriteLine("StaticConstrucEx2Outer " + typeof(T).Name);
}
public class StaticConstrucEx2Inner<U, V> {
static StaticConstrucEx2Inner() {
Console.WriteLine("Outer <{0}> : Inner <{1}><{2}>",
typeof(T).Name,
typeof(U).Name,
typeof(V).Name);
}
public static void FooBar() {}
}
public class SCInner {
static SCInner() {
Console.WriteLine("SCInner init <{0}>", typeof(T).Name);
}
public static void FooBar() {}
}
}
StaticConstrucEx2Outer<int>.StaticConstrucEx2Inner<string, DateTime>.FooBar();
StaticConstrucEx2Outer<int>.SCInner.FooBar();
StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, DateTime>.FooBar();
StaticConstrucEx2Outer<string>.SCInner.FooBar();
StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, Int16>.FooBar();
StaticConstrucEx2Outer<string>.SCInner.FooBar();
StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, UInt32>.FooBar();
StaticConstrucEx2Outer<long>.StaticConstrucEx2Inner<string, UInt32>.FooBar();
Будет выдан следующий результат
Outer <Int32> : Inner <String><DateTime>
SCInner init <Int32>
Outer <String> : Inner <String><DateTime>
SCInner init <String>
Outer <String> : Inner <String><Int16>
Outer <String> : Inner <String><UInt32>
Outer <Int64> : Inner <String><UInt32>
Недавно я узнал о методе String.Join. Это действительно полезно при построении строк, таких как столбцы, для выбора по запросу.