2009-03-06 2 views
1

Хорошо. Поэтому у меня есть список значений, и я хотел бы сделать примерно следующее:Инициализация объекта и «Идиома именованного конструктора»

MyObjectValues 
.Select(currentItems=>new MyType() 
{ 
    Parameter1 = currentItems.Value1, 
    Parameter2 = currentItems.Value2 
}); 

Так вот в чем проблема. Мне нужен приведенный выше пример для работы с именованными конструкторами, такими как:

MyObjectValues 
.Select(currentItems=>MyType.GetNewInstance() 
{ 
    Parameter1 = currentItems.Value1, 
    Parameter2 = currentItems.Value2 
}); 

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

EDIT: В настоящее время у меня нет простого способа изменить интерфейс MyType, поэтому добавление новых вызовов функций (хотя, вероятно, и «лучший» подход) в настоящий момент не очень практично.

ответ

1

К сожалению, нет никакой прямой поддержки этого в C# 3.0. Инициализаторы объектов: только поддерживается для вызовов конструктора. Однако вы можете рассмотреть шаблон Builder. В моем порту протокола Буферы, я поддерживаю это так:

MyType foo = new MyType.Builder {Parameter1 = 10, Parameter2 = 20}.Build(); 

Так что ваш пример станет:

MyObjectValues.Select(currentItems => new MyType.Builder 
{ 
    Parameter1 = currentItems.Value1, 
    Parameter2 = currentItems.Value2 
}.Build()); 

Конечно, это означает, что написание вложенного типа Builder, но он может работать достаточно хорошо. Если вы не возражаете против MyType , строго говоря, mutable, вы можете оставить неизменяемый API, но сделать экземпляр Builder немедленно создать новый экземпляр MyType, а затем установить свойства по мере его поступления (так как он имеет доступ к закрытым членам) и затем, наконец, верните экземпляр MyType в методе Build(). (Затем он должен «забыть» экземпляр, так что дальнейшая мутация запрещена.)

2

Я уверен, что кто-то подумает об умном способе сделать это в версии 4.0 C#, но я просто прочитал Sam Ng's blog post on named parameters in C# 4.0. Это должно решить вашу проблему. Это будет выглядеть следующим образом:

MyObjectValues.Select(currentItems=>MyType.GetNewInstance(
    Parameter1:currentItems.Value1, 
    Parameter2:currentItems.Value2)); 

EDIT

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

+0

Это выглядит полезным, когда оно прибывает. – GWLlosa

1

Update: как о заводе:

MyObjectValues.Select(currentItems=>MyTypeFactory.GetNewInstance(currentItems.Value1, 
currentItems.Value2)); 


public static class MyTypeFactory 
{ 
    public static MyType GetNewInstance(
     typeofvalue1 value1, 
     typeofvalue2 value2) 
    { 
     return new MyType { Parameter1 = value1, Parameter2 = value2 }; 
    } 
} 
+0

У меня нет простого способа изменить реализацию MyType в этом экземпляре. – GWLlosa

+0

С фабрикой вам не нужно изменять MyType, используйте только MyTypeFactory –