假设我有一个定义了几个实体接口的类库:
public interface ISomeEntity { /* ... */ }
public interface ISomeOtherEntity { /* ... */ }
这个库还定义了一个IRepository
接口:
public interface IRepository<TEntity> { /* ... */ }
最后,该库有一个名为RepositorySourceBase
(见下文)的抽象类,主项目需要实现它。此类的目标是允许基类Repository
在运行时获取新对象。因为需要某些存储库(在此示例中为ISomeEntity
and的存储库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
and 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();
}
}
}
}