在我的应用程序中,我需要为多个类定义一组相同的常量值,并且我想使用它们的一个基类/接口作为我的泛型类的类型参数。
//I know following code will not work, just trying to demonstrate the problem
public interface IConstantsDefined
{
static const string DbName;
static const string TableName;
static const string ColumnName;
}
public static class Product : IConstantsDefined
{
public static const string DbName = "ProductDB";
public static const string TableName = "Products";
public static const string ColumnName = "ProductId";
}
public static class Sales: IConstantsDefined
{
public static const string DbName = "SalesDb";
public static const string TableName = "Sales";
public static const string ColumnName = "SaleId";
}
public class DbConnection<TConsts> where TConsts : IConstantsDefined
{
// use TConsts.DbName, TConsts.TableName here
}
我明白我上面写的内容会在C#中引发很多错误。我知道静态类不能从接口继承。我的问题是,构建这样一个系统的最佳设计/方法是什么,记住性能和内存?
答案 0 :(得分:2)
常量被定义并初始化一次。
public interface IConstantsDefined
{
static const string Foo = "Foo";
static const string Bar = "Bar";
}
你想要的是抽象的get-only字段:
public interface IConstantsDefined
{
string DbName { get };
string TableName { get };
string ColumnName { get };
}
public class Product : IConstantsDefined
{
public string DbName { get { return "ProductDB" } };
public string TableName { get { return "Products" } };
public string ColumnName { get { return "ProductId" } };
}
public class Sales: IConstantsDefined
{
public string DbName { get { return "ProductDB" } };
public string TableName { get { return "Sales" } };
public string ColumnName { get { return "SaleId" } };
}
由于您不需要/想要产品和销售类型的多个实例,您可能需要考虑完全删除类型,因为这几乎是类的定义:
public class ConstantsDefined
{
public string DbName { get; private set; };
public string TableName { get; private set; };
public string ColumnName { get; private set; };
public static readonly ConstantsDefined Product = new ConstantsDefined()
{
DbName = "ProductDB",
TableName = "Products",
ColumnName = "ProductId",
};
}
答案 1 :(得分:0)
您可以在@nabuchodonossor的评论中尝试。或者,您可以创建实现接口IMetadata的元数据类,ProductMetadata和SalesMetadata。然后在需要时,您可以通过传入实际的模型信息(例如,typeof(Sales))来使用工厂来获取元数据实例。
答案 2 :(得分:0)
最接近想要的是使用基本抽象类:
abstract class Base
{
public abstract string DbName { get; }
}
class Product : Base
{
public override string DbName => "ProductDB";
}
class Sales : Base
{
public override string DbName => "SalesDB";
}
class DbConnection<T> where T : Base
{
public string Test(T instance) => instance.DbName;
}
这确实需要instance
,可由DbConnection
保留,由服务提供商等解决。
我的所有产品或销售类都有各种常量,所以我不想创建这些实例
这个要求基本上改变了一切。您似乎将给定上下文中的常量理解为“无法更改的值”。哪个是不可变的类型。那么你不需要泛型来构造带有常量的类型,只需传递参数(就像你对任何不可变类型那样):
class DbConnection
{
public string DbName { get; }
public DbConnection(string dbName)
{
DbName = dbName;
}
}
用法:您只需new DbConnection<Product>()
而不是神秘的new DbConnection("ProductDB")
。如果你有多个参数,那么考虑包装它们并将实例传递给构造函数。这就是我在第一个代码段中最终得到抽象类和非静态继承的地方:new DbConnection(new Product())
(而DbConnection
需要Base
类型才能通过)。