Скрытые возможности C #? [закрыто]

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);

Для получения дополнительной информации см. здесь

1476
задан 56 revs, 31 users 10% 25 September 2017 в 20:53
поделиться

295 ответов

Свойство "TODO" и список задач

//TODO: [something] 

Добавление этого свойства в ваш код (интервал важен) бросает элемент в список задач, и двойной щелчок по элементу переместит вас в соответствующее место в вашем коде.

.
3
ответ дан 22 November 2019 в 20:21
поделиться

Я не знал об общих методах, которые могли бы помочь избежать перегрузки методами. Ниже приведены перегруженные методы для вывода 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);
        }
    }
3
ответ дан 22 November 2019 в 20:21
поделиться
  • Прикрепление ? к Типу, чтобы сделать это. недействительный, бывший: int?
  • "c:\dir" вместо @ "C:\dir"
4
ответ дан 22 November 2019 в 20:21
поделиться

Я просто хочу упомянуть (из-за OP Metioning, где t: struct), что один из C # Compiler Gotchas состоит в том, что

where T : Enum

не скомпилируется. Это бросает ошибку «ограничение не может быть специальным классом» System.enum '».

4
ответ дан 22 November 2019 в 20:21
поделиться

Инициализатор коллекции внутри инициализатора объекта:

MailMessage mail = new MailMessage {
   To = { new MailAddress("a@example.com"), new MailAddress("b@example.com") },
   Subject = "Password Recovery"
};

Вы можете инициализировать целое дерево в одном выражении.

4
ответ дан 22 November 2019 в 20:21
поделиться

Я немного опоздал в этом разговоре и хотел бы внести следующий вклад. Это может быть новым для некоторых разработчиков.

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"
};
4
ответ дан 22 November 2019 в 20:21
поделиться

Одной из наиболее полезных функций Visual Studio является «Создание идентификатора объекта». Он генерирует идентификатор и «прикрепляется» к объекту, поэтому, где бы вы ни смотрели на объект, вы также увидите идентификатор (независимо от потока).

Во время отладки щелкните правой кнопкой мыши всплывающую подсказку для переменных, и вот она. Она также работает с переменными watched / autos / locals.

4
ответ дан 22 November 2019 в 20:21
поделиться

Это относится к статическим конструкторам. Это метод статического уничтожения (т.е. очистки ресурсов при выходе из программы).

Сначала о классе:

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);
        }
    }
}

Когда программа завершается, вызывается «статический деструктор».

4
ответ дан 22 November 2019 в 20:21
поделиться

Я не оправдываю это, но я был удивлен, что goto все еще существует утки от входящих снарядов

4
ответ дан 22 November 2019 в 20:21
поделиться

Не скрытый, но крутой. Я нахожу это более сжатой заменой для простого 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 
1
ответ дан 22 November 2019 в 20:21
поделиться

Имея дело с взаимодействием между 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.

2
ответ дан 22 November 2019 в 20:21
поделиться

Если вы хотите запретить сборщику мусора запускать финализатор объекта, просто используйте GC.SuppressFinalize (object); . Аналогично, GC.KeepAlive (object); не позволит сборщику мусора собрать этот объект, ссылаясь на него. Не очень часто используется, по крайней мере, по моему опыту, но полезно знать на всякий случай.

1
ответ дан 22 November 2019 в 20:21
поделиться

Отражение настолько сильное, когда используется осторожно. Я использовал его в системе шаблонов электронной почты. В диспетчер шаблонов будет передан объект, а в шаблоны html будут встроены поля, которые ссылаются на свойства, которые можно получить из переданного объекта с помощью отражения. Получилось очень красиво.

2
ответ дан 22 November 2019 в 20:21
поделиться

Фильтры исключений . Итак, «скрытые» вы не можете даже использовать их (по крайней мере, из C #) без патча после компиляции;)

1
ответ дан 22 November 2019 в 20:21
поделиться

Когда вам необходимо (а) синхронно обмениваться данными между объектами о возникновении события, существует специальный интерфейс, называемый 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));
}
1
ответ дан 22 November 2019 в 20:21
поделиться

Не уверен, что Microsoft понравится этот вопрос, особенно с таким количеством ответов. Я уверен, что однажды я слышал, как глава Microsoft сказал:

скрытая функция - это бесполезная функция

... или что-то в этом роде.

2
ответ дан 22 November 2019 в 20:21
поделиться

Использование @ перед строкой, содержащей escape-символ. Обычно, когда для присвоения строковой переменной используется физический путь, все используют '\', где в строке присутствует escape-символ.

например string strPath = "D: \ sites \ web1 \ images \";

Но escape-символы можно игнорировать, используя @ перед строковым значением.

например строка strPath = @ "D: \ sites \ web1 \ images \";

2
ответ дан 22 November 2019 в 20:21
поделиться

Не знайте, является ли это секретом по сути, но я любил добавленное Счетное (добавляет к 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

3
ответ дан 22 November 2019 в 20:21
поделиться

Другой способ получить IEnumerable через доходность без объяснения причин, создавая IEnumerable объект

public IEnumerable<Request> SomeMethod(IEnumerable<Request> requests)
{
    foreach (Request request in requests)
       yield return DoSomthing(request);
}
2
ответ дан 22 November 2019 в 20:21
поделиться

Я не знаю, является ли это скрытой функцией (""). Любая строковая функция.

0
ответ дан 22 November 2019 в 20:21
поделиться

Этот трюк для вызова частных методов с помощью Delegate.CreateDelegate очень удобен.

var subject = new Subject();
var doSomething = (Func<String, String>)
    Delegate.CreateDelegate(typeof(Func<String, String>), subject, "DoSomething");
Console.WriteLine(doSomething("Hello Freggles"));

Вот контекст, в котором это полезно

2
ответ дан 22 November 2019 в 20:21
поделиться

Большая часть P / Invoke немного странная.

Пример атрибутов:

[DllImport ("gdi32.dll")] 
[return : MarshalAs(UnmanagedType.I4)]
[StructLayout(LayoutKind.Sequential)]
2
ответ дан 22 November 2019 в 20:21
поделиться

Что касается сообщения с постоянной ссылкой « Скрытые возможности 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

Я не уверен, что это неизвестная функция!

3
ответ дан 22 November 2019 в 20:21
поделиться

Разделите статические поля в зависимости от универсального типа окружающего класса.

    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>
1
ответ дан 22 November 2019 в 20:21
поделиться

Недавно я узнал о методе String.Join. Это действительно полезно при построении строк, таких как столбцы, для выбора по запросу.

3
ответ дан 22 November 2019 в 20:21
поделиться