gpt4 book ai didi

C# 工厂方法与泛型强制转换为接口(interface)

转载 作者:行者123 更新时间:2023-11-30 14:13:31 30 4
gpt4 key购买 nike

我有以下类(class):

// -- model hierarchy
public interface IJob {
}

public abstract class AbstractJob : IJob {
}

public class FullTimeJob : AbstractJob {
}

// -- dao hierarchy
public interface IJobDao<T> where T : IJob {
T findById(long jobId);
long insert(T job);
}

public interface IFullTimeJobDao : IJobDao<FullTimeJob> {
}

public abstract class AbstractDao {
}

public abstract class AbstractJobDaoImpl<T> : AbstractDao, IJobDao<T> where T : IJob {
public T findById(long jobId) {
// omitted for brevity
}

public long insert(T job) {
// omitted for brevity
}
}

public class FullTimeJobDaoImpl : AbstractJobDaoImpl<FullTimeJob>, IFullTimeJobDao {
}

我正在从工厂方法中调用以下代码,但它似乎不起作用:

public IJobDao<IJob> createJobDao(long jobDaoTypeId)
{
object jobDao = Activator.CreateInstance(typeof(FullTimeJobDaoImpl));
return jobDao as IJobDao<IJob>; // <-- this returns null
return (IJobDao<IJob>) jobDao; // <-- this cast fails
}

如何正确实现这种“向上转换”?

最佳答案

制作IJobDao接口(interface)协变:

public interface IJobDao<out T> where T : IJob
{
T findById(long jobId);
}

更新:

您不能让接口(interface)方法既返回又接受泛型值并同时使其协变。

可能的解决方案:

  • 创建一个非通用版本的IJobDao<T> - IJobDao (当然,你必须在类中实现这两个接口(interface),实现 IJobDao<T> )
  • 拆分IJobDao<T>分为 2 个接口(interface)(一个协变和一个逆变)
  • 考虑仅使用非通用接口(interface)的解决方案 IJobDao (无论如何,你在这里没有得到任何类型安全,这是泛型的主要目的)

实现第一个场景的一些想法:

public interface IJobDao
{
IJob findById(long jobId);

long insert(IJob job);
}

public interface IJobDao<T> : IJobDao
where T : IJob
{
new T findById(long jobId);

new long insert(T job);
}

public abstract class JobDaoBase<T> : IJobDao<T>, IJobDao
where T : IJob
{
public abstract T findById(long jobId);

public abstract long insert(T job);

IJob IJobDao.findById(long jobId)
{
return findById(jobId);
}

long IJobDao.insert(IJob job)
{
return insert((T)job);
}
}

public class FullTimeJobDaoImpl : JobDaoBase<FullTimeJob>
{
public override FullTimeJob findById(long jobId)
{
// implementation
}

public override long insert(FullTimeJob job)
{
// implementation
}
}

// we are still unable to return generic interface, but we don't need to.
public static IJobDao createJobDao(/* my params */)
{
object jobDao = Activator.CreateInstance(typeof(FullTimeJobDaoImpl));
return jobDao as IJobDao;
}

关于C# 工厂方法与泛型强制转换为接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14035653/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com