Скрытые возможности 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 ответов

Вместо того, чтобы делать что-то глупое, как это:

Console.WriteLine("{0} item(s) found.", count);

Я использую следующий встроенный трюк:

Console.WriteLine("{0} item{1} found.", count, count==1 ? "" : "s");

Это будет отображать «элемент», когда есть один элемент, или «элементы», когда их больше ( или меньше) чем 1. Не много усилий для немного профессионализма.

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

Встроенный делегат MethodInvoker (2.0) полезен, когда вы хотите вызвать встроенный код Invoke / BeginInvoke. Это позволяет избежать необходимости создавать фактический делегат и отдельный метод.

    void FileMessageEvent(object sender, MessageEventArgs e)
    {

        if (this.InvokeRequired == true)
        {
            this.BeginInvoke((MethodInvoker)delegate { 
                     lblMessage.Text=e.Message; 
                     Application.DoEvents(); 
                 }
            ); 

        }
    }

Устраняет ошибку: «Невозможно преобразовать анонимный метод в тип System.Delegate, потому что это не тип делегата».

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

Инициализация массива без указания типа элемента массива:

var pets = new[] { "Cat", "Dog", "Bird" };
7
ответ дан 22 November 2019 в 20:21
поделиться

Свойства, отображаемые при просмотре компонентов Свойства в режиме конструктора:

7
ответ дан 22 November 2019 в 20:21
поделиться
HttpContext.Current.Server.Execute 

отлично подходит для рендеринга HTML в строки для обратных вызовов AJAX. Вы можете использовать это с компонентом вместо того, чтобы собирать вместе фрагменты строки HTML. Мне удалось уменьшить размер страницы на пару сотен КБ практически без лишнего шума. Я использовал его так:

Page pageHolder = new Page();
UserControl viewControl = (UserControl)pageHolder.LoadControl(@"MyComponent.ascx");
pageHolder.Controls.Add(viewControl);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();
7
ответ дан 22 November 2019 в 20:21
поделиться

Advanced Debugging

Display

уже упомянутые атрибуты DebuggerDisplay и DebuggerBrowsable управляют видимостью элементов и отображаемым текстовым значением. Простое переопределение ToString () заставит отладчик использовать вывод этого метода. доступны здесь .

Son Of Strike

Microsoft предоставляет расширение отладчика, известное как SOS . Это чрезвычайно мощное (хотя и часто сбивающее с толку) расширение, которое является отличным способом диагностики «утечек», точнее, нежелательных ссылок на объекты, которые больше не требуются.

Сервер символов для исходного кода инфраструктуры

Следуя этим инструкциям позволит вам пройти через исходный код некоторых частей фреймворка.

Изменения в 2010 году

В Visual Studio 2010 есть несколько улучшений и новых функций:

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

You can create delegates from extension methods as if they were regular methods, currying the this parameter. For example,

static class FunnyExtension {
    public static string Double(this string str) { return str + str; }
    public static int Double(this int num) { return num + num; }
}


Func<string> aaMaker = "a".Double;
Func<string, string> doubler = FunnyExtension.Double;

Console.WriteLine(aaMaker());       //Prints "aa"
Console.WriteLine(doubler("b"));    //Prints "bb"

Note that this won't work on extension methods that extend тип значения; см. этот вопрос .

7
ответ дан 22 November 2019 в 20:21
поделиться
[field: NonSerialized]
public event EventHandler Event;

Таким образом, прослушиватель событий не сериализуется.

Just [NonSerialized] не работает, потому что NonSerializedAttribute может применяться только к полям.

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

Выражение для инициализации словаря в C # 3.5:

новый словарь <строка, Int64> () {{"Тестирование", 123}, {"Тест", 125}};

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

Не думаю, что кто-то упомянул это добавление? после имени типа значения сделает его допускающим значение null.

Вы можете сделать:

DateTime? date = null;

DateTime - это структура.

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

Возможность использовать LINQ для выполнения встроенной работы с коллекциями, которые раньше выполняли итерации и условные выражения, может быть невероятно ценной. Стоит узнать, как все методы расширения LINQ могут помочь сделать ваш код более компактным и удобным в обслуживании.

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

C# allows you to add property setter methods to concrete types that implement readonly interface properties even though the interface declaration itself has no property setter. For example:

public interface IReadOnlyFoo
{
   object SomeReadOnlyProperty { get; }
}

The concrete class looks like this:

internal class Foo : IReadOnlyFoo
{
   public object SomeReadOnlyProperty { get; internal set; }
}

What's interesting about this is that the Foo class is immutable if you cast it to the IReadOnlyFoo interface:

// Create a Foo instance
Foo foo = new Foo();

// This statement is legal
foo.SomeReadOnlyProperty = 12345;

// Make Foo read only
IReadOnlyFoo readOnlyFoo = foo;

// This statement won't compile
readOnlyFoo.SomeReadOnlyProperty = 54321;
8
ответ дан 22 November 2019 в 20:21
поделиться

Инициализаторы словарей всегда полезны для быстрых взломов и модульных тестов, когда вам нужно жестко закодировать некоторые данные.

var dict = new Dictionary<int, string> { { 10, "Hello" }, { 20, "World" } };
8
ответ дан 22 November 2019 в 20:21
поделиться

Чтобы проверить, пуст ли IEnumerable с LINQ, используйте:

IEnumerable .Any ();

  • Сначала я использовал (IEnumerable .Count ()! = 0) ...
    • Что излишне вызывает перечисление всех элементов в IEnumerable .
  • В качестве улучшения я использовал (IEnumerable .FirstOrDefault () == null) ...
    • Который лучше ...
  • Но IEnumerable .Any () является наиболее кратким и работает лучше всего.
9
ответ дан 22 November 2019 в 20:21
поделиться

С LINQ можно создавать новые функции на основе параметров. Это очень хорошо, если у вас есть крошечная функция, которая выполняется очень часто, но для расчета параметров требуется некоторое время.

    public Func<int> RandomGenerator
    {
        get
        {
            var r = new Random();
            return () => { return r.Next(); };
        }
    }

    void SomeFunction()
    {
        var result1 = RandomGenerator();

        var x = RandomGenerator;
        var result2 = x();
    }
8
ответ дан 22 November 2019 в 20:21
поделиться

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

AmbientValueAttribute

Это похоже на DefaultValueAttribute , но вместо того, чтобы указывать значение, которое свойство по умолчанию он предоставляет значение, которое свойство использует, чтобы решить, запрашивать ли его значение откуда-то еще. Например, для многих элементов управления в WinForms их свойства ForeColor и BackColor имеют значение AmbientValue из Color.Empty , чтобы они знали, что получают свои цвета из родительского элемента управления.

IsolatedStorageSettings

Это цвет Silverlight. Платформа легко включает в себя этот запечатанный класс для обеспечения постоянства настроек как на уровне приложения, так и на уровне сайта.

Взаимодействие флагов с методами расширения

Использование методов расширения делает использование перечисления флагов более читаемым.

    public static bool Contains(
          this MyEnumType enumValue,
          MyEnumType flagValue)
    {
        return ((enumValue & flagValue) == flagValue);
    }

    public static bool ContainsAny(
          this MyEnumType enumValue,
          MyEnumType flagValue)
    {
        return ((enumValue & flagValue) > 0);
    }

] Это делает проверки значений флагов удобными и удобными для чтения и записи. Конечно, было бы лучше, если бы мы могли использовать дженерики и заставить T быть перечислением, но это не разрешено. Возможно, dynamic упростит эту задачу.

но это запрещено. Возможно, dynamic упростит эту задачу.

но это запрещено. Возможно, dynamic упростит эту задачу.

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

Я нахожу невероятным, какие проблемы компилятор переживает, чтобы сахар запрограммируйте использование внешних переменных :

string output = "helo world!";
Action action = () => Console.WriteLine(output);
output = "hello!";
action();

Это фактически напечатает hello! . Зачем? Поскольку компилятор создает вложенный класс для делегата с общедоступными полями для всех внешних переменных и вставляет код настройки перед каждым отдельным вызовом делегата :) Вот код, отраженный выше:

Action action;
<>c__DisplayClass1 CS$<>8__locals2;
CS$<>8__locals2 = new <>c__DisplayClass1();
CS$<>8__locals2.output = "helo world!";
action = new Action(CS$<>8__locals2.<Main>b__0);
CS$<>8__locals2.output = "hello!";
action();

Довольно я думаю круто.

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

Я не мог понять, для чего использовались некоторые функции из класса Convert (например, Convert.ToDouble (int), Convert.ToInt (double)) пока я не объединил их с Array.ConvertAll :

int[] someArrayYouHaveAsInt;
double[] copyOfArrayAsDouble = Array.ConvertAll<int, double>(
                                someArrayYouHaveAsInt,
                                new Converter<int,double>(Convert.ToDouble));

Что позволяет избежать проблем с распределением ресурсов, возникающих из-за определения встроенного делегата / закрытия (и немного более читаемого):

int[] someArrayYouHaveAsInt;
double[] copyOfArrayAsDouble = Array.ConvertAll<int, double>(
                                someArrayYouHaveAsInt,
                                new Converter<int,double>(
                                  delegate(int i) { return (double)i; }
                                ));
6
ответ дан 22 November 2019 в 20:21
поделиться

Только что изучив значение инвариантности, ковариантности и контравариантности, я обнаружил общие модификаторы в и вне , которые будут включены в .NET 4.0 . Они кажутся достаточно неясными, чтобы большинство программистов не знали о них.

В Visual Studio Magazine есть статья , в которой обсуждаются эти ключевые слова и то, как они будут использоваться.

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

Тип данных может быть определен для перечисления:

enum EnumName : [byte, char, int16, int32, int64, uint16, uint32, uint64]
{
    A = 1,
    B = 2
}
6
ответ дан 22 November 2019 в 20:21
поделиться

Ключевое слово Yield часто упускается из виду, когда оно имеет большую силу. Некоторое время назад я писал об этом в блоге и обсуждал преимущества (различная обработка) и происходящее под капотом yield, чтобы помочь лучше понять.

Использование Yield в C #

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

Указатели в C #.

Их можно использовать для обработки строк на месте. Это небезопасная функция, поэтому ключевое слово unsafe используется для обозначения области небезопасного кода. Также обратите внимание, как ключевое слово fixed используется для обозначения того, что указанная память закреплена и не может быть перемещена сборщиком мусора. Это очень важно, указатели указывают на адреса памяти, и сборщик мусора может перемещать память на другой адрес, иначе это приведет к недействительному указателю.

    string str = "some string";
    Console.WriteLine(str);
    unsafe
    {
        fixed(char *s = str)
        {
            char *c = s;
            while(*c != '\0')
            {
                *c = Char.ToUpper(*c++);                    
            }
        }
    }
    Console.WriteLine(str);

Я бы никогда не стал этого делать, но просто ради этого вопроса, чтобы продемонстрировать эту функцию.

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

Мне особенно нравится DateTime, допускающий значение NULL. Поэтому, если у вас есть случаи, когда указывается дата, и другие случаи, когда дата не указывается, я думаю, что это лучше всего использовать, и ИМХО легче понять как использование DateTime.MinValue или чего-то еще ...

DateTime? myDate = null;

if (myDate.HasValue)
{
    //doSomething
}
else
{
    //soSomethingElse
}
6
ответ дан 22 November 2019 в 20:21
поделиться

Открытые универсальные шаблоны - еще одна удобная функция, особенно при использовании Инверсия управления :

container.RegisterType(typeof(IRepository<>), typeof(NHibernateRepository<>));
6
ответ дан 22 November 2019 в 20:21
поделиться
[

] Прочитав все 9 страниц, я почувствовал, что должен указать на маленькую неизвестную особенность...[

] [

]Это было верно для .NET 1.1, используя сжатие/декомпрессию на gzipped файлах, нужно было либо:[

] [
    ] [
  • ]Скачать []ICSharpCode. ZipLib[][
  • ] [
  • ]Или сослаться на библиотеку Java в вашем проекте и использовать встроенную библиотеку Java, чтобы воспользоваться преимуществами методов сжатия/декомпрессии GZip.[
  • ] [
] [

]Она недоиспользуется, о которой я не знал, (все равно используйте ICSharpCode. ZipLib до сих пор, даже с .NET 2/3.5) был включен в стандартную BCL версию 2 вверх, в пространство имён System.IO.Compression... см. страницу MSDN "[]GZipStream Class[]".[

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

Я нахожу использование функции условного разрыва в Visual Studio очень полезной. Мне нравится, как он позволяет мне установить значение для чего-то, что, например, можно встретить только в редких случаях, и оттуда я могу дальше изучить код.

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

Это означает, что T должен иметь общедоступный конструктор без параметров:

 class MyClass<T> where T : new()
 {

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

Я читал книгу «Pro ASP.NET MVC Framework» (APress) и заметил, что автор делал с объектом Dictionary это было чуждо мне.

Он добавил новую пару ключ / значение без использования метода Add (). Затем он перезаписал ту же самую пару ключ / значение, не проверяя, существует ли уже этот ключ. Например:

Dictionary<string, int> nameAgeDict = new Dictionary<string, int>();
nameAgeDict["Joe"] = 34;      // no error. will just auto-add key/value
nameAgeDict["Joe"] = 41;      // no error. key/value just get overwritten
nameAgeDict.Add("Joe", 30);   // ERROR! key already exists

Во многих случаях мне не нужно проверять, есть ли в моем Словаре ключ или нет, и я просто хочу добавить соответствующую пару ключ / значение (при необходимости перезаписав существующую пару ключ / значение. .) До этого открытия мне всегда приходилось проверять, существует ли уже ключ, прежде чем добавлять его.

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

Доступ к локальным переменным из анонимных методов позволяет вам обернуть практически любой код новой логикой потока управления без необходимости переносить этот код в другой метод. Локальные переменные, объявленные вне метода, доступны внутри метода, например, локальная переменная endOfLineChar в примере здесь:

http://aaronls.wordpress.com/2010/02/02/retrying-on -exception-conditionally /

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