比方說,我有一個類庫,定義了兩個實體的接口:麻煩抽象的通用方法
public interface ISomeEntity { /* ... */ }
public interface ISomeOtherEntity { /* ... */ }
該庫還定義了一個IRepository
接口:
public interface IRepository<TEntity> { /* ... */ }
最後,圖書館一個叫RepositorySourceBase
的抽象類(見下文),主要項目需要實現。這個類的目標是允許基類在運行時獲取新的對象。因爲需要某些存儲庫(在本例中爲ISomeEntity
和ISomeOtherEntity
的存儲庫),所以我試圖編寫GetNew<TEntity>()
方法的泛型重載。
下實現不編譯(第二GetNew()
方法被標記爲「已定義」,即使在where子句是不同的),但它得到什麼,我試圖完成:
public abstract class RepositorySourceBase // This doesn't work!
{
public abstract Repository<TEntity> GetNew<TEntity>()
where TEntity : SomeEntity;
public abstract Repository<TEntity> GetNew<TEntity>()
where TEntity : SomeOtherEntity;
}
這個類的預期用途會是這樣的:
public class RepositorySourceTester
{
public RepositorySourceTester(RepositorySourceBase repositorySource)
{
var someRepository = repositorySource.GetNew<ISomeEntity>();
var someOtherRepository = repositorySource.GetNew<ISomeOtherEntity>();
}
}
同時,比我的主項目(引用庫項目),我公頃已經的ISomeEntity
和ISomeOtherEntity
實現:
public class SomeEntity : ISomeEntity { /* ... */ }
public class SomeOtherEntity : ISomeOtherEntity { /* ... */ }
主要項目也已經爲IRepository<TEntity>
實現:
public class Repository<TEntity> : IRepository<TEntity>
{
public Repository(string message) { }
}
而且最重要的是,它具有抽象RepositorySourceBase
的實現:
public class RepositorySource : RepositorySourceBase
{
public override IRepository<ISomeEntity> GetNew()
{
return new (IRepository<ISomeEntity>)Repository<SomeEntity>(
"stuff only I know");
}
public override IRepository<ISomeOtherEntity> GetNew()
{
return new (IRepository<ISomeEntity>)Repository<SomeOtherEntity>(
"other stuff only I know");
}
}
與RepositorySourceBase
一樣,第二個GetNew()
方法獲取標記爲「已定義」。
所以,C#基本上認爲我重複着同樣的方法,因爲沒有辦法來區分他們的參數單獨的方法,但是如果你看一下我的使用例子,好像我應該能夠以區分哪個GetNew()
我想要的泛型類型參數,例如,<ISomeEntity>
或<ISomeOtherEntity>
)。
我需要做些什麼才能使其發揮作用?
更新
我最終解決這個使用專門命名方法和Func<T, TResult>
參數。
所以,RepositorySourceBase
現在看起來是這樣的:
public abstract class RepositorySourceBase
{
public abstract Repository<ISomeEntity> GetNewSomeEntity();
public abstract Repository<ISomeOtherEntity> GetNewSomeOtherEntity();
}
而且RepositorySource
看起來是這樣的:
public class RepositorySource : RepositorySourceBase
{
public override IRepository<ISomeEntity> GetNewSomeEntity()
{
return new (IRepository<ISomeEntity>)Repository<SomeEntity>(
"stuff only I know");
}
public override IRepository<ISomeOtherEntity> GetNewSomeOtherEntity()
{
return new (IRepository<ISomeEntity>)Repository<SomeOtherEntity>(
"other stuff only I know");
}
}
現在,開始這件事過了,我需要一個通用的RepositoryUtilizer
類可能只需知道存儲庫的類型(可將其指定爲泛型類型參數)即可從源獲取存儲庫。原來,這是不可能的(或者至少不容易)。但是,是可能的是使用Func<T, TResult>
委託作爲參數,以允許RepositoryUtilizer
類獲取存儲庫,而無需「知道」方法名稱。
下面是一個例子:
public class RepositoryUtilizer
{
public DoSomethingWithRepository<TEntity>(
Func<TRepositorySource, IRepository<TEntity>> repositoryGetter)
{
using (var repository = repositoryGetter(RepositorySource))
{
return repository.DoSomething();
}
}
}
}
+1。感謝您的回答和鏈接,Eric。我設法實現了我使用專門命名的方法(如你所建議的)和一個'Func'參數尋找的結果,該參數允許我使用lambda表達式從源獲取存儲庫。不像只能指定我想要的類型那麼漂亮,但它基本上完成了我一直在尋找的「通用性」的程度:) – devuxer 2010-05-15 18:19:19