sticky
FAQ - .NET Base Class Library Mini FAQ

Все ответы

  • 1. Как сравнить два DateTime объекта?

    Для  того, чтобы сравнить DateTime объекты используйте операторы сравнения <,>,==,!= или используйте метод DateTime.Compare(). Чтобы получить разницу между DateTime объектами, просто вычтите из одного объекта другой, результатом вычитания будет объект TimeSpan, который и будет содержать разницу.


    Для связи [mail]
    12 ноября 2010 г. 13:37
  • 2. Какая разница между (int), Int32.Parse и Convert.ToInt32?

    (int) – явное приведение типа. Переменные источника и назначения должны быть совместимы для выполнения приведения, также существует риск потери данных, т.к. тип переменной назначения может иметь меньший размер, чем переменная источник. См. таблицу преобразования

    Int32.Parse – метод только для конвертации строки в число.

    Convert – класс, который упрощает преобразования между базовыми типами.
    Convert.ToInt32(String, IFormatProvider) аналогичен методу Int32.Parse, однако в случае null строки Convert вернет 0, в то время как Int32.Parse сгенерирует исключение ArgumentNullException. Convert.ToInt32 также сгенерирует исключение, если переданное число больше Int32.MaxValue или меньше ToInt32.MinValue.
    Convert.ToInt32 округляет значение до ближайшего целого. В случае, когда дробная часть равна 0.5, число округляет до ближайшего четного (например для 4.5 результат будет равен 4, а для 5.5 – 6.)

    Для большей информации читайте:
    Casting and Type Conversions (C# Programming Guide)
    Преобразование типов в Visual Basic


    Для связи [mail]
    12 ноября 2010 г. 13:49
  • 3. Как можно преобразовать hex строку в decimal/long число?

    Для преобразования шестнадцатеричной строки в decimal/long число нужно вызвать метод long.Parse() с параметром NumberStyle.HexNumber, или вызвать Convert.ToInt64() с параметром основания 16.

      string hex = "FF";
      long L1 = long.Parse(hex, System.Globalization.NumberStyles.HexNumber);
      MessageBox.Show(L1.ToString());
      long L2 = Convert.ToInt64(hex,16);
      MessageBox.Show(L2.ToString());
    


    Для связи [mail]
    13 ноября 2010 г. 6:34
  • 4. Есть ли эквивалент в C# для функции IsDate из VB.

    В C# нету подобной функции, однако, Вы можете вызвать метод DateTime.TryParse для проверки входной объект объектом времени.

        public static bool IsDate(object Expression)
        {
          if (Expression != null)
          {
            if (Expression is DateTime)
            {
              return true;
            }
            if (Expression is string)
            {
              DateTime time1;
              return DateTime.TryParse((string)Expression, out time1);
            }
          }
          return false;
        }



    Для связи [mail]
    13 ноября 2010 г. 6:39
  • 5. Как получить значение максимально допустимого пути/имени директории.

    Не существует встроенной константы или перечисления, которые предоставляли бы эту информацию. В данный момент вам придется жестко в коде указать эти данных.

    см. Naming Files, Paths, and Namespaces


    Для связи [mail]
    13 ноября 2010 г. 6:46
  • 6. Как конвертировать строку в int, double и т.д.

    Для этого можно использовать класс Convert. Этот класс содержит много статических методов, которые помогут вам. Также проверяйте наличие метода Parse у типа, в который вы хотите преобразовать строку.


    Для связи [mail]
    13 ноября 2010 г. 6:47
  • 7. Как использовать класс  SerialPort для простой последовательной связи?

    SerialPort класс используется для управления файловым ресурсом последовательного порта. Данный класс предоставляет возможности управления вводом-выводом в синхронном режиме или на основе событий, доступа к состоянию линии и состоянию разрыва, а также доступа к свойствам последовательного драйвера. Кроме того, функции этого класса можно упаковать во внутренний объект Stream, доступный через свойство BaseStream, и передавать в классы, использующие потоки или служащие для них оболочкой.


    Для связи [mail]
    13 ноября 2010 г. 6:49
  • 8. Как я могу проверить используется ли файл?

    Общий способ проверки доступности файла это - попробовать открыть файл в try блоке, и если файл используется кем-то другим, то мы получим исключение IOException

        public bool IsFileLocked(string filename)
        {
          bool Locked = false;
          try
          {
            FileStream fs =
              File.Open(filename, FileMode. OpenOrCreate,
              FileAccess.ReadWrite, FileShare.None);
            fs.Close();
          }
          catch (IOException ex)
          {
            Locked = true;
          }
          return Locked;
        }
    

    Другой путь проверки доступности файла – это воспользоваться WinAPI функцией CreateFile и проверить возвращенный результат.

      [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      private static extern SafeFileHandle CreateFile(string lpFileName,
      FileSystemRights dwDesiredAccess, FileShare dwShareMode, IntPtr
      securityAttrs, FileMode dwCreationDisposition, FileOptions
      dwFlagsAndAttributes, IntPtr hTemplateFile);
    
        const int ERROR_SHARING_VIOLATION = 32;
    
        private bool IsFileInUse(string fileName)
        {
          bool inUse = false;
    
          SafeFileHandle fileHandle = 
          CreateFile(fileName, FileSystemRights.Modify, 
             FileShare.Write, IntPtr.Zero,         
             FileMode.OpenOrCreate, FileOptions.None, IntPtr.Zero);
    
          if (fileHandle.IsInvalid)
          {
            if (Marshal.GetLastWin32Error() == 
              ERROR_SHARING_VIOLATION)
            {
       			  inUse = true; // файл используется
            }      
          }
          fileHandle.Close();
          return inUse;
        }
    


    Для связи [mail]
    13 ноября 2010 г. 6:54
  • 9. Как запустить другое приложение из .NET?

    Вы можете использовать Process.Start метод для запуска другой программы из .NET. Также вы можете задать параметры запуска приложения используя класс ProcessStartInfo, который позволяет задать параметры командной строи, перенаправить вывод и т.д. Классы ProcessStartInfo и Process находятся в пространстве имен System.Diagnostics.

    Однако, Вы также можете использовать вызов API метода CreateProcess, предварительно импортировав его с помощью P/Invoke.


    Для связи [mail]
    13 ноября 2010 г. 6:56
  • 10. Как сделать, чтобы нельзя было запустить более одного экземпляра приложения?

    Лучшим способом достижения этого является использование именованного мьютекса. Создать мьютекс можно так:

      bool firstInstance;
      Mutex mutex = new Mutex(false, "Local\\" + 
              someUniqueName, out firstInstance);
      // Если firstInstance = true, то мы запустили первый экземпляр приложения
      // В противном случае – попытка запустить второй экземпляр
    
    Обратите внимание, что мьютекс создается локальный (“Local\\”), т.е. он существует только в сессии текущего пользователя. Если этого не сделать, то мьютекс будет разделяемым между пользователями и несколько различных пользователей не смогут одновременно работать с программой. Также стоит отметить, что вызов ResealeMutex необязателен, мьютекс автоматически освободится, когда главный процесс завершится.

    Единственное чего следует остерегаться, так это освобождения мьютекса раньше времени. Если локальная переменная используется только вначале метода, то GC может удалить ее раньше, чем вы ожидаете. Чтобы этого не случилось в конце метода нужно вызвать GC.KeepAlive (mutex). Или, в качестве альтернативы, можно использовать статическую переменную для хранения объекта мьютекса. Это обеспечит сохранения мьютекса до того, пока AppDomain не будет выгружен.

     

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

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



    Для связи [mail]
    13 ноября 2010 г. 6:58
  • 11. Имеет ли .NET возможности для сжатия/архивирования данных?

    В версии 1.1 .NET Framework не содержал каких либо общих классов для сжатия данных. В версии 2.0 и выше появилось новое пространство имен System.IO.Compression, которое содержит классы для сжатия и распаковки данных. В частности классы GZipStream и DeflateSteam предоставляют методы сжатия и распаковки файлов внутри zip архивов.


    Для связи [mail]
    13 ноября 2010 г. 7:04
  • 12. Как получить атрибуты сборки в рантайме?

    Большинство атрибутов сборки (которые как правило указываются в AssemblyInfo.cs) доступны по средством использования метода Assembly.GetCustomAttributes(). Например, чтобы получить название сборки:

       Assembly asm = this.GetType().Assembly;
       object[] attrs = asm.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
       if (attrs.Length == 1)
       {
          Console.WriteLine(((AssemblyTitleAttribute)attrs[0]).Title);
       }
    

    AssemblyTitleAttribute возвращает только часть имени, которая также может быть получена с помощью метода Assembly.GetName(). Чтобы получить имя сборки с помощью GetName(), нужно:

       Assembly asm = this.GetType().Assembly;
       Console.WriteLine(asm.GetName().Name);
    


    Для связи [mail]
    13 ноября 2010 г. 7:08
  • 13 .  Как можно создать экземпляр типа, зная только его имя?

    Первое что нужно сделать, это получить Type объект для данного типа. Если тип находится в выполняемой в данный момент сборке или библиотеке Mscorlib.dll, достаточно предоставить имя типа с указанием пространства имен, это можно сделать с помощью Type.GetType(name). Если в другой сборке, то имя, передаваемое в Type.GetType() должно содержать  имя сборки например myNamespace.myClass,MyAssembly, где MyAssembly – имя сборки.

    Как только вы получите объект Type, можно вызвать Activator.CreateInstance(объект Type), чтобы создать экземпляр конструктором по умолчанию. Или можно с помощью метода GetConstructor() объекта Type получить конкретный конструктор, который потом использовать для создания экземпляра приложения, через вызов метода Invoke() конструктора.

    using System;
    using System.Reflection;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
          Type myt = Type.GetType("ConsoleApplication1.test");
          object f = Activator.CreateInstance(myt); // конструктор по умолчанию
          ConstructorInfo[] info = myt.GetConstructors();
          info[1].Invoke(new[] { "parametrized constructor" }); // параметризированный
          
        }
      }
    
      public class test
      {
        public test()
        {
          Console.WriteLine("default constructor");
        }
    
        public test(string text)
        {
          Console.WriteLine(text);
        }
      }
    }



    Для связи [mail]
    13 ноября 2010 г. 7:13
  • 14. Как подписаться на событие, используя рефлексию.

    При использовании рефлексии для загрузки и запуска сборок невозможно использовать функциональные возможности языка, такие как += в C# или AddHandler в VisualBasic, для подписку на событие. Статья на MSDN показывает, как подписаться на событие, используя рефлесию.


    Для связи [mail]
    13 ноября 2010 г. 7:20
  • 15. Как можно следить за изменениями файла или папки?

    Используйте класс FileSystemWatcher для слежения за изменениями в необходимой папке. Также вы может следить и за изменениями в файлах и подпапках нужной папки. Этот компонент может следить за файлами на локальном компьютере, сетевом носителе, а также на удаленном компьютере.


    Для связи [mail]
    13 ноября 2010 г. 7:22
  • 16. Как конвертировать длинный путь в короткий?

    В Framework нету функции для конвертации длинного имени в короткое. Можно использовать WinAPI фукнцию GetShortPathName, импортировав ее через P/Invoke.

    using System.Runtime.InteropServices;
    

    Сигнатура функции:

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int GetShortPathName(string longPath,
          [MarshalAs(UnmanagedType.LPTStr)]StringBuilder ShortPath,
          [MarshalAs(UnmanagedType.U4)]int bufferSize);
    


    Для связи [mail]
    13 ноября 2010 г. 7:25
  • 17. Как конвертировать элемент перечисления в строку?

    Есть 2 пути для конвертации элемента перечисления в строку:

    string enumEntryAsString = Enum.GetName(typeof(MyEnum), MyEnum.First);
    

    или

    MyEnum e = MyEnum.First;
    string enumEntryAsString = e.ToString();
    


    Для связи [mail]
    13 ноября 2010 г. 7:26