Как создать две перегрузки конструктора, каждая из которых принимает только один строковый параметр? - PullRequest
6 голосов
/ 15 февраля 2011

Например, вы хотите, чтобы объект мог быть инициализирован двумя способами, используя путь к файлу и строку. Обычно оба конструктора должны принимать один строковый параметр, MyObject(string file) и MyObject(string content), но перегрузить таким способом невозможно. Что вы предлагаете?

Редактировать : В первом случае также необходим путь к файлу, поэтому, пожалуйста, не предлагайте решение, которое считывает содержимое файла и просто передает его другому конструктору.

Ответы [ 7 ]

15 голосов
/ 15 февраля 2011

Я не программист C #, но это похоже на работу для статического метода фабрики pattern:

class MyObject {
  public static MyObject FromContent(string content) {
    return new MyObject(content);
  }

  public static MyObject FromFile(string path) {
    return new MyObject(ReadContentFromFile(path));
  }
}

Тогда вы можете сделать

MyObject object = MyObject.FromFile("/some/path");

, что даже более читабельно, чем использование обычного конструктора.

10 голосов
/ 15 февраля 2011

Возможно, вы могли бы изменить первым, чтобы принять FileInfo вместо:

class MyObject
{
    public MyObject(FileInfo file) { /* etc... */ }
    public MyObject(string content) { /* etc... */ }
}

...

MyObject o = new MyObject(new FileInfo(filename));
1 голос
/ 15 февраля 2011
1 голос
/ 15 февраля 2011

Может быть, вы можете использовать фабрику?

class MyObjectProvider
{
   public static MyObject CreateByPath(string path) 
   { 
      return new MyObject
              {
                  Path = path;
              };

   }

   public static MyObject CreateByContent(string content) 
   { 
      return new MyObject
              {
                  Content = content;
              };
   }
}
1 голос
/ 15 февраля 2011

Или создайте фабричные методы:

public static MyObject CreateByFilePath(string path){ ... }
public static MyObject CreateByContent(string content){ ... }
0 голосов
/ 15 февраля 2011

Я возьму противоположный подход и скажу: не делай этого.Лучшее из опубликованных решений (использование альтернативного типа, такого как FileInfo или Uri для одной из перегрузок) мне кажется немного хакерским - идет вразрез с принципом наименьшего удивления.

Если вы можете построить, используясодержание только без имени файла, следовательно, имя файла не является обязательным.И точно так же, если вы можете создать только с именем файла, из этого следует, что содержание не является существенным.Предположительно вы можете впоследствии установить отсутствующее имя файла / содержимое позже, например, установив свойство:

MyObject myObject = new MyObject(fileName);
myObject.Content = ...

MyObject myObject = new MyObject(content);
myObject.FileName = ...

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

public MyObject(string fileName) : this(fileName, null)
{
}

public MyObject(string fileName, string content)
{
    ... implementation
}

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

public MyObject(string fileName, string content)
{
    if (fileName == null && content == null) throw new ArgumentException(...);
    ...
}    

Короче, не используйте хаки для обхода подобных ограничений.

0 голосов
/ 15 февраля 2011
public MyObject(Uri fileUri);
public MyObject(string content);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...