C # - переопределение некоторых классов, доступных в пространстве имен системы - PullRequest
4 голосов
/ 16 марта 2011

У меня есть проект, который необходимо скомпилировать в Compact .NET Framework 3.5 и .NET Framework 3.5 (на самом деле это 2 проекта, просто компиляция параметров, которые изменяются между обоими). ​​

Проблема в том, что некоторые классы отсутствуют в CF .NET, поэтому я создал его вручную (и реализовал все члены класса, доступные в .NET

Один пример: классы FtpWebRequest / FtpWebResponse.

Плохо писать что-то вроде этого (если да, то почему?):

#if CFNET35 // Only if we are in Compact Framework 3.5 mode
namespace System.Net
{
    public class FtpWebRequest : WebRequest
    {
        // ...
    }

    public class FtpWebResponse : WebResponse
    {
        // ...
    }
}
#endif

Я уверен, что в CF.NET35 эти методы никогда не будут доступны, поэтому я могу написать это?

Я бы написал это, чтобы избежать конфликта имен при использовании библиотеки my в проектах.

Это позволяет мне в других проектах всегда using System.Net;, не спрашивая меня, какой фреймворк я использую ...

Спасибо!


EDIT

Несколько месяцев спустя я бы оценил стратегию, которую использовал.

Как уже было сказано, я переопределяю пространство имен System (.Net), выполняя условную компиляцию, поэтому у меня есть две библиотеки DLL (одна для CF.NET, другая для .NET)

Это также включает в себя то, что все мои приложения, использующие эту DLL, находятся в двойном формате (каждый раз приложение CF.NET и одно приложение .NET, которое включает соответствующую библиотеку).

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

Более того, я не позаботился о том, чтобы приложение .NET включало библиотеку CF.NET с переопределенным пространством имен System, его инициализация не удалась из-за конфликта имен классов ...

Итак, EPIC FAIL , обеспечивающий универсальный интерфейс, является лучшим способом управления этим делом.

Ответы [ 4 ]

6 голосов
/ 16 марта 2011

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

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

Это может показаться излишним, но в будущем вам будет безопаснее, если что-то будет в System.Netизменения.Ваш код вызова должен просто ссылаться на интерфейс, и вы можете подключить любую реализацию в зависимости от того, на какой платформе вы находитесь.

// Shared interface
public interface IFtpUtil
{
    SomeFileObject GetFile(SomeArgument a);
    void PutFile(SomeFileObject f, SomeArgument a);
}

// Full framework implementation
public class FullFtpUtil : IFtpUtil
{
    public ... GetFile(...)
    {
        // Use System.Net classes from full framework
    }

    public ... PutFile(...)
    {
        // Use System.Net classes from full framework
    }
}

// Compact framework implementation
public class CompactFtpUtil : IFtpUtil
{
    public ... GetFile(...)
    {
        // Use your own FTP classes
    }

    public ... PutFile(...)
    {
        // Use your own FTP classes
    }
}
5 голосов
/ 16 марта 2011

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

Классы в пространстве имен System были тщательно протестированы и использованы многими людьми, поэтому, если кто-то в вашей команде использует System.Net.FtpWebRequest в своем коде и его код не работает, он будет (и должен) искать для ошибок в их собственном коде в первую очередь. После многих часов поиска они будут сердиться на вас, когда узнают, что ошибка была в явно встроенном системном классе.

1 голос
/ 09 января 2012

Я понимаю, что опаздываю к этому вопросу, но я думаю, что могу добавить некоторую ценность, так как мы делаем это много.SDF, вероятно, на 50% заполнен для классов, соответствующих настольной платформе.Мы использовали наше собственное пространство имен.Итак, давайте посмотрим на Ftp в качестве примера.Мы сделаем это:

namespace OpenNETCF.Net

public class FtpWebRequest  { ... }

Для решения этой задачи в приложении для пользователя будет использоваться псевдоним:

#if NETCF
using FtpWebRequest = OpenNETCF.Net.FtpWebRequest;
#else
using FtpWebRequest = System.Net.FtpWebRequest;
#endif

void Foo()
{
    // the alias above resolves these for you
    // enabling a single, fairly clean code base
    var request = new FtpWebRequest(...);
}
0 голосов
/ 28 марта 2011

Был похожий случай.Хотите использовать некоторые пространства имен / классы, доступные в среде winforms, но удалены из мобильной платформы.

Я предлагаю не помещать ваши пространства имен в пространство имен "system", но я предлагаю разработать свой код, каккак можно ближе к фреймворку, если только ваше приложение.требуется определенная дополнительная функциональность.

using system;

// "sysmobile" emulates code for the "system" namespace

namespace sysmobile {
  class FtpWebRequest { ... }
  class FtpWebResponse { ... }
}
...