2013-03-27 2 views
3

Я получаю следующую ошибку.C# Generic Constrains Issue

Типа «Test.ICacheProvider» не может быть использован в качестве параметра типа «» TStorageProvider в универсальном типе или методы «StorageManager.Test.IFileInfo». Нет никакого неявного эталонного преобразования от «StorageManager.Test.ICacheProvider» до «StorageManager.Test.IStorageProvider».

Неправильно ли внутри этой структуры дизайна проекта?

Программа:

// Cache Provider Classes 

public interface ICacheProvider { } 

public class BaseCacheProvider : ICacheProvider { } 

public class DerivedCacheProvider : BaseCacheProvider { } 

// Storage Classes 
public interface IStorageProvider<TCacheProvider> where TCacheProvider : 
    ICacheProvider { } 

public interface BaseStorageProvider<TCacheProvider> : 
    IStorageProvider<TCacheProvider> where TCacheProvider : ICacheProvider { } 

public interface DerivedStorageProvider : BaseStorageProvider<ICacheProvider> { } 

// User Classes 
public interface IFileInfo<TStorageProvider> 
    where TStorageProvider : IStorageProvider<ICacheProvider> { } 

public class FileInfo : IFileInfo<ICacheProvider> { } 
+2

Не могли бы вы показать нам строку, которая производит ошибку? – Carsten

+0

Ошибка в строке объявления класса FileInfo. –

+0

Я пропустил что-то в этой программе? –

ответ

7

Ошибка в определении FileInfo класса. Вы устанавливаете параметр шаблона в ICacheProvider, но ограничение состоит в том, что аргумент шаблона должен быть IStorageProvider<ICacheProvider>.

Это, вероятно, будет лучше:

public interface FileInfo 
      : IFileInfo<IStorageProvider<ICacheProvider>> 

Даже ваши имена не совпадают: IFileInfo потребности хранения провайдера, но вы даете ему кэш провайдера.

+1

Или изменить объявление ICacheProvider на: 'public interface ICacheProvider: IStorageProvider ' –

+0

@MatthewWatson: Может ли 'ICacheProvider' иметь ограничение, которое требует, чтобы он был аргументом типа другого интерфейса ?! – Carsten

+0

Это не имеет смысла. Вы можете только сдерживать то, что не известно заранее. Вы можете «ограничить» один интерфейс, чтобы гарантировать, что он наследует другого. –

1

Ваши ограничения missmatching:

// User Classes 
public interface IFileInfo<TStorageProvider> 
    where TStorageProvider : IStorageProvider<ICacheProvider> { } 

public class FileInfo : IFileInfo<ICacheProvider> { } 

FileInfo объявлен как IFileInfo с родовым аргументом типа ICacheProvider. Однако IFileInfo имеет ограничение, которое позволяет принимать только IStorageProvider s. И ICacheProvider не является IStorageProvider.