#c# #.net #generics
#c# #.net #дженерики
Вопрос:
Я пытаюсь создать что-то очень похожее на то, как EF Core использует строителей в своей конфигурации сущностей (например, , IEntityTypeConfigurationlt;TEntitygt;
, EntityTypeBuilderlt;TEntitygt;
, PropertyBuilderlt;TEntitygt;
).
В приведенном ниже коде я хотел бы ObjectBuilderlt;gt;
, чтобы класс и SubObject()
метод выводили тип из класса, в котором они реализованы (в данном случае MyClass
). Возможно ли это?
Было бы также здорово, если бы я мог вывести второй тип из реализуемого интерфейса ( SomeType
тип), но я почти уверен, что это невозможно.
Возможно, мне нужен совершенно другой подход к этому, но мне еще предстоит придумать альтернативное решение.
Спасибо вам за помощь.
public interface ISomeInterfacelt;T2gt; { } public class SomeType { public string MySubObjectField { get; } public string MySubObjectField2 { get; } } public class MyClass : ISomeInterfacelt;SomeTypegt; { public string MyObjectField { get; } public string MyObjectField2 { get; } public MyClass() { ObjectBuilderlt;MyClass, SomeTypegt; builder = new ObjectBuilderlt;MyClass, SomeTypegt;(); builder .SubObjectlt;MyClassgt;(c =gt; c.MyObjectField) .HasSomething(t =gt; t.MySubObjectField) .IsSomething(); builder .SubObjectlt;MyClassgt;(c =gt; c.MyObjectField2) .HasSomething(t =gt; t.MySubObjectField2); } } public class ObjectBuilderlt;T1, T2gt; { public SubObjectBuilderlt;T2gt; SubObjectlt;T1gt;(Expressionlt;Funclt;T1, objectgt;gt; expression) { // Simplified for question return new SubObjectBuilderlt;T2gt;(); } } public class SubObjectBuilderlt;T2gt; { public SubObjectBuilderlt;T2gt; HasSomething(Expressionlt;Funclt;T2, objectgt;gt; expression) { // Do something return this; } public SubObjectBuilderlt;T2gt; IsSomething() { // Do something return this; } }
Комментарии:
1. Не могли бы вы лучше описать, что вы хотели бы сделать. У вас есть 4 класса и определенный интерфейс. Моя голова взрывается всякий раз, когда я читаю: «класс ObjectBuilder выводит тип из класса, в котором он создается» . Внутреннее сбивает меня с толку. Одним из идиоматических трюков при построении шаблонных классов является создание статического (не универсального) заводского класса с тем же именем. Добавьте статический
Createlt;Tgt;
универсальный метод, которыйT
можно вывести из параметров вCreate
. В методе body создайте новый экземпляр универсального класса. Я не могу сказать, поможет ли это вам2. Для вывода типа требуется что-то на сайте вызова. Тип, который объявляет метод, в него не входит, равно как и параметры типов произвольных интерфейсов, которые он реализует. Предложение Flydog57 о a
Createlt;Tgt;
с параметрами типов для вывода является распространенным решением. Однако, если речь идет только о краткости, рассмотрите возможность использования либоvar
одного, либо довольно новогоnew
синтаксиса целевого типа, чтобы исключить дублирование имени типа с аргументами типа.3. @Flydog57, я пытаюсь создать что-то очень похожее на то, как EF Core использует конструкторы в своей конфигурации сущностей (например, ,
IEntityTypeConfigurationlt;TEntitygt;
,EntityTypeBuilderlt;TEntitygt;
,PropertyBuilderlt;TEntitygt;
). Перечитав это предложение еще раз, вы правы, что оно не имеет смысла.ObjectBuilder
Класс на самом деле не находится внутриMyClass
. Экземпляр создается внутриMyClass
, ноObjectBuilder
сам об этом не знает. У меня было такое чувство, что так оно и было. Я обязательно посмотрю на статическую фабрику для этого и посмотрю, будет ли она соответствовать моим потребностям. Спасибо!4. Лучше всего, если вы поместите эту информацию в вопрос и отредактируете ее в целом, чтобы сделать ее более понятной
5. Я фактически решил проблему, добавив конкретный тип реализации в качестве общего параметра в интерфейсе :
ISomeInterfacelt;MyClass, SomeTypegt;
. Это позволило мне передать параметр типа вSubObject()
метод, а не повторять его каждый раз. Я понимаю, что мой вопрос на самом деле не показал реальной проблемы, с которой я столкнулся, а именно, чтоSubObject
метод требовал параметра типа каждый раз, когда он вызывался. Я предполагаю, что объяснение этого привело бы к более быстрому ответу. Мои извинения. Спасибо вам обоим за вашу помощь.