Выведите аргумент типа из содержащего класса

#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 метод требовал параметра типа каждый раз, когда он вызывался. Я предполагаю, что объяснение этого привело бы к более быстрому ответу. Мои извинения. Спасибо вам обоим за вашу помощь.