ИЗМЕНИТЬ, чтобы показать реальный пример
Как я могу вызвать универсальную функцию из универсального типа, переданного в функцию? Кажется, это должно быть интуитивно понятно, но я не могу заставить его работать.
Например, могу ли я вызвать функцию cache.ResetCache () в LocalDataObjectEngine ниже?
Я получаю сообщение об ошибке: «Тип T нельзя использовать в качестве параметра».
public interface ISimpleCache<T1>
{
...
void ResetCache<T>() where T : T1;
}
internal class LocalDataObjectEngine_Cache : ISimpleCache<IBrokeredDataObject>
{
ISimpleCache<IBrokeredDataObject> _cache;
...
public void ResetCache<T>() where T : IBrokeredDataObject
{
//logic here
}
...
}
public partial class LocalDataObjectEngine : IEngine
{
ISimpleCache<IBrokeredDataObject> _cache = new LocalDataObjectEngine_Cache();
public void ResetCache<T>() where T : IBrokeredDataObject
{
_cache.ResetCache<T>();
}
}
}





Я не уверен, что происходит, если только в вашем определении IBrokeredDataObject что-то не написано. То, что вы написали, мне кажется правильным и компилируется.
[Отредактировано в соответствии с редакцией OP]
Прежде всего, зачем вам указывать универсальный тип в ваших методах? В классе уже указан универсальный тип, вы получите доступ к нему в своих методах:
public interface ISimpleCache<T1>
{
...
void ResetCache();
}
что значительно упрощает класс, реализующий интерфейс:
internal class LocalDataObjectEngine_Cache : ISimpleCache<IBrokeredDataObject>
{
ISimpleCache<IBrokeredDataObject> _cache;
...
public void ResetCache();
{
//logic here with access to IBrokeredDataObject if needed
}
...
}
то же самое касается последнего метода, просто вызовите
_cache.ResetCache();
однако, если вам действительно нужно указать универсальный тип в методах по какой-либо причине, выполните следующие действия.
Давайте начнем:
Почему бы вам не использовать T1 в методе вместо того, чтобы указывать T должно быть похоже на T1?
public interface ISimpleCache<T1>
{
...
void ResetCache<T1>();
}
В вашем LocalDataObjectEngine_Cache вам не нужно снова указывать T, просто используйте IBrokeredDataObject (если вы не реализуете метод и щелкните правой кнопкой мыши имя интерфейса, чтобы выбрать «Реализовать интерфейс», он запишет его, как показано ниже:
internal class LocalDataObjectEngine_Cache : ISimpleCache<IBrokeredDataObject>
{
ISimpleCache<IBrokeredDataObject> _cache;
...
public void ResetCache<IBrokeredDataObject>();
{
//logic here
}
...
}
Затем из вашего последнего класса просто вызовите его снова, указав фактический класс, которым вы хотите, чтобы T был:
public partial class LocalDataObjectEngine : IEngine
{
ISimpleCache<IBrokeredDataObject> _cache = new LocalDataObjectEngine_Cache();
public void ResetCache<IBrokeredDataObject>()
{
_cache.ResetCache<IBrokeredDataObject>();
}
}
Поэтому сброс кеша ResetCache <IBrokeredDataObject> не будет соответствовать моим требованиям, поскольку я не могу указать движку удалить все DerivedDataObjectType1, а не DerivedDataObjectType2 из кеша.
Пока ваш класс реализует IBrokeredDataObject, вы можете использовать его при объявлении объекта _cache. ISimpleCache <SomeClassThatImplementsTheInterface> _cache = new ... будет работать.
После удаления ..., ссылки на IEngine, и предоставления пустого интерфейса IBrokeredDataObject ваш код компилируется без каких-либо проблем.
Пожалуйста, предоставьте короткий, но полный пример, который компилирует не. В идеале создайте новый проект с одним файлом, поместите туда весь свой код и сделайте его как можно проще, показывая ту же ошибку. Затем просто вырезайте и вставьте сюда. Таким образом, нам не нужно исправлять "..." и т. д. Или удалять ссылки на интерфейсы, для которых у нас нет объявлений.
Спасибо, я опубликовал ответ, именно ваша ссылка на IEngine помогла мне найти виновника
Нашел, ссылка Джона Скита на удаление IEngine указала мне в правильном направлении, была
void ResetCache<T>() where T : IDataObject
на IEngine (IDataObject является базой для IBrokeredDataObject), который я изменил на
void ResetCache<T>() where T : IBrokeredDataObject
Спасибо всем за то, что терпели мою ошибку, +1 всем вам
Я хотел различать T1 как базовый объект кеша и T как типизированный объект, производный от T, поскольку в кеше может находиться от 0 до n различных типов объектов, все производные от IBrokeredDataObject, но я хочу указать один типа смыть.