【问题标题】:C# inherited casting membersC# 继承的强制转换成员
【发布时间】:2012-02-04 05:26:31
【问题描述】:

我正在为我的实体框架数据库上下文类开发一个基类。在基类中我需要访问 DbContext,在派生类中我需要访问派生 DbContext。目前我有以下代码:

 public abstract class BaseClass: IDisposable   
{
    protected abstract DbContext BaseContext { get; }

    public void Dispose()
    {
        if (BaseContext != null)
        {
            BaseContext.Dispose();
        }
    }
}

public class DerivedClass : BaseClass
{
    DerivedContext context; // public class DerivedContext: DbContext

    protected override DbContext BaseContext 
    {
        get
        {
            return context;
        }           
    }
}

这是一个正确的方法吗?

【问题讨论】:

标签: c# .net inheritance casting


【解决方案1】:

至少您的IDisposable 实现必须改进。您应该执行以下操作:

IDisposable 示例:

public class BaseClass : IDisposable
{
    private bool _disposed = false;
    protected DbContext Context { get; }

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        // Check to see if Dispose has already been called.
        if (!this._disposed)
        {
            // If disposing equals true, dispose all managed
            // and unmanaged resources.
            if (disposing)
            {
                // Disposes managed resources here
                if (this.Context != null)
                {
                    this.Context.Dispose();
                }
            }

            // Disposes unmanaged resources here
            // NOTHING HERE

            // Note disposing has been done.
            this._disposed = true;
        }
    }
}

对于DBContext 本身,这取决于您打算如何使用它。

【讨论】:

    【解决方案2】:

    根据您需要在派生类中做多少非常特殊的事情,您也可以首先采用通用方法。从此你也可以继承。

    public class BaseClass<TContext> : IDisposable   
       where TContext : IContext
    {
    
        public TContext Context { get; private set; }
    
        public void Dispose()
        {
            if (Context != null)
            {
                Context.Dispose();
            }
        }
    
        public BaseClass(TContext context)
        {
           this.Context = context;
        }
    }
    
    public interface IContext : IDisposable
    {
    
    }
    
    public ChildClass : BaseClass<MyContext>
    {
       public ChildClass(MyContext context)
         : base(context)
       {
       }
    }
    

    【讨论】:

      【解决方案3】:

      您不希望域对象依赖于 dbcontext。该域应该不了解 dbcontex。 回答你的问题:不,这不是“正确的”。

      您可能拥有的是围绕域对象分层的一系列组件,这些组件使用 dbcontext 加载/保存实体。

      【讨论】:

      • 我不确定您为什么认为 BaseClass 和 DerivedClass 是域对象。这个问题似乎没有表明这一点。
      • @cadrell0 第二次阅读 OP,你的权利。由于@Jani 留下的关于 AR 的评论,我假设了一个域对象。
      【解决方案4】:

      这在某种程度上取决于您希望如何使用它。您发布的代码将始终将派生上下文与派生类的实例一起使用,并将基上下文与基类一起使用。

      // This code gets an instance of the DerivedContext.
      BaseClass myBase = new DerivedClass();
      DbContext myContext = myBase.BaseContext;
      

      如果这是您想要的工作方式,那么您使用的是正确的方法。

      【讨论】:

        【解决方案5】:

        我会建议类似的东西

        public abstract class BaseClass<TContext> : IDisposable 
            where TContext : DbContext
        {
            //not abstract
            protected TContext Context { get; private set; }
        }
        
        public class DerivedClass : BaseClass<DerivedContext>
        {
            ....
        }
        

        在您的基类中,您可以访问 DbContext 的所有成员,在您的 DerivedClass 中,您可以访问 DervedContext 的所有成员,而无需强制转换。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-17
          • 1970-01-01
          • 1970-01-01
          • 2012-04-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多