Трудно сказать, учитывая, что вы указали только два объявления, а не то, как вы их используете. Является ли IdT другим параметром типа где-нибудь? (Если бы это было TId
, что хотел бы предложить это - но тот факт, что вы используете EntityT
для другого параметра типа, в отличие от конвенций, свидетельствует о том, что может быть IdT
как хорошо ...)
Теперь, предполагая, что IdT
является на самом деле Guid
в вашем случае, как должен компилятор работать, что вы имеете в виду Foo
? Могут быть другие типы, происходящие от EntityObject<Guid>
.
Короче говоря, вы не дали нам достаточно информации, чтобы что-то сказать наверняка, но похоже, что вы в основном делаете необоснованные требования к компилятору.
EDIT: Хорошо, вот моя догадка, что у вас есть, используя обычные правила именования:
public interface IRepository
{
TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId>
}
public abstract class EntityObject<TId>
{
public IdT id { get; set; }
}
public class Foo : EntityObject<Guid> {}
Вы хотите сделать:
IRepository repository = GetRepositoryFromSomewhere();
Foo foo = repository.Get<Foo>(someGuid);
В то время как в настоящее время вы должны сделать:
Foo foo = repository.Get<Foo, Guid>(someGuid);
Да, компилятор делает это очень немного сложнее для вас, чем необходимо. Целые 6 дополнительных символов, для упрощения понимания языка и определения типа вывода.
В принципе, вывод типа - это все или ничего: все параметры выведены или ни один из них не является. Это упрощает работу, так как вам не нужно определять, какие из них указаны, а какие нет. Это часть проблемы, а другая часть является то, что вы можете выразить только ограничения на параметры типа метода - вы не можете иметь:
class Repository<TEntity>
{
TEntity Get<TId>(TId id) where TEntity : EntityObject<TId>
}
потому что это сдерживающий TEntity
, не TId
. Опять же, подобные вещи делают вывод типа проще.
Теперь вы мог потенциально написать:
Foo foo = repository.Get(someGuid).For<Foo>();
с соответствующим Get
способом и дополнительным интерфейсом. Я думаю, я лично предпочел бы просто использовать Get<Foo, Guid>
.
Jon, Извините, что не добавлял больше деталей. Опять же, это было больше, чем вопрос манжеты, а не действительно законный вопрос. Но imho компилятор должен иметь возможность определять IdT из объекта foo во время компиляции. Скорее всего, это мои предположения для дженериков, которые приводят меня к ошибочной интерпретации того, как компилятор мог/должен был прочитать это, но я предположил, что общий тип не был определен до момента компиляции, после чего компилятор затем связал шаблонный объект. Предполагая, что, не было бы еще одним шагом определить тип ссылочного объекта? – Raspar
Generics! = Шаблоны. Вероятно, вы могли бы заставить компилятор C++ «вывести» что-то вроде этого, но до тех пор, пока генерики не исполняются, я не вижу, чтобы это происходило без более четкого общего определения. – user7116
IdT не является параметром типа 'Get', который имеет только один параметр типа' EntityT'. Вы не дали объявление IRepository, или то, что не работает для вас. Пожалуйста, дайте * полный * пример, показывающий, что вы * пытаетесь * сделать и рассказываете нам, что происходит, а не то, что вы хотите. –