【问题标题】:Using inherited members from base class (moving repeatable code into base class)使用从基类继承的成员(将可重复的代码移动到基类中)
【发布时间】:2015-02-02 16:39:33
【问题描述】:

我经常用

using (var context = new SomeDataContext(SomeDataContext.ConnectionString))
{
   ...
}

在哪里

abstract class DataContextBase: DataContext { ... }

partial class SomeDataContext: DataContextBase
{
    public const string DatabaseFile = "blablabla.mdf";
    public static readonly string ConnectionString = string.Format(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", DatabaseFile);
}

问题:是否可以隐藏 SomeDataContext 实例和 ConnectionString 的创建到 DataContextBase 深处?

我只想在继承的类中定义文件名

partial class SomeDataContext: DataContextBase
{
    public const string DatabaseFile = "blablabla.mdf";
}

并且能够创建这样的实例

var context = SomeDataContext.PropertyInBaseClassWhichCreatesInstanceOfInheritedClass;

P.S.:我首先添加了我是如何尝试克服问题的(没有成功),但后来我删除了它(我在一个小时内发布了这篇文章!),因为它使问题变得太吵了。起初看起来很容易,直到你(或者只有我?)尝试解决它。我将其标记为dbml,因为特定于DataContext 的东西:你不能使用单例等等。

【问题讨论】:

  • 你能控制这两个类,还是它们是生成的?
  • @BradleyDotNET,是的,但是partial 一个部分(它是自动生成的)=P

标签: c# architecture dbml


【解决方案1】:

不幸的是,there isn't some sort of virtual static,如果你调用SomeDataContext.StaticPropertyInBaseClass,它会编译成DataContextBase.StaticPropertyInBaseClass。我认为你能做的最好的事情是这样的:

// upside: simple SomeDataContext.Instance for external users
// downside: more code in SomeDataContext
partial class SomeDataContext : DataContextBase
{
    private const string DatabaseFile = "blablabla.mdf";
    public static SomeDataContext Instance
    {
        get
        {
            return new SomeDataContext(GetConnectionString(DatabaseFile));
        }
    }
}
abstract class DataContextBase
{
    protected static string GetConnectionString(string databaseFile)
    {
        return string.Format(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", databaseFile);
    }
}
// e.g. using (var context = SomeDataContext.Instance)

或者

// upside: just one line in child class
// downside: a little harder for external callers, with a little less type safety
// downside: as written, requires child class to have parameterless constructor
partial class SomeDataContext : DataContextBase
{
    protected override string DatabaseFileInternal { get { return "blablabla.mdf"; } }
}
abstract class DataContextBase
{
    protected abstract string DatabaseFileInternal { get; }
    private string ConnectionString
    {
        get
        {
            return string.Format(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", DatabaseFileInternal);
        }
    }
    public static T GetInstance<T>() where T : DataContextBase, new()
    {
        using (var tInst = new T())
            return (T)Activator.CreateInstance(typeof(T), tInst.ConnectionString);
    }
}
// e.g. using (var context = DataContextBase.GetInstance<SomeDataContext>())

【讨论】:

  • 感谢您的回答。我想到了这两个=P。泛型的问题是没有new(someParameter) 约束,并且每次调用都构造实例(我不确定它是否无害,因为它是自动生成的类),但返回另一个使用反射生成的实例。所以第一个可能是最好的。提问时,我希望得到一些不自然的答案(或有趣的答案,以代表为例)。
  • 关于带参数的构造函数的约束,可以是单例(只获取名称,可以调用非静态方法),其中包含以委托为参数的方法,如here。重点是,如果可能的话,还有更多方法要移入基类,我需要找到正确的方法。
猜你喜欢
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 2018-08-01
  • 2017-04-14
  • 2013-05-04
  • 1970-01-01
  • 2021-08-09
  • 2021-11-15
相关资源
最近更新 更多