0

我正在为一个稀有数据库的驱动程序编写一个包装器。具体来说,我正在实现原始查询代码,所以我自然需要尽可能快的速度。这将在大型电子商务解决方案中实施。

这让我远离了动态类型和强制转换。我想直接访问实际的数据类型。

我需要的功能是有一个带有通用字段的基本参数类,以及一系列子类,每个子类都有一个特定类型的字段(每个数据库类型一个,它们是 int、long、double、string、byte[]、object、和列表,加上每种类型的列表)。C# 类型应与数据库类型匹配。

这并不简单,因为在我的实现中,调用代码需要查看基本类型,但基本类型看不到子字段。

这是我到目前为止的代码:

private abstract class GlobalQueryParam
{
    public readonly string Low;
    // Val must be correctly typed
    public abstract object Val; // requires casting; don't want, but works
    protected string dbVal = "";        

    public string GetDBVal()
    {
        return this.dbVal;
    }

    public abstract bool SetDBVal(string value);

    public GlobalQueryParam(string low)
    {
        this.Low = low;
    }
}

public class GlobalQueryParamInt : GlobalQueryParam
{
    /// <summary>
    /// Represents the current literal value. Used in traversal actions.
    /// </summary>
    public override int Val;

    public int Parse(string dbVal)
    {
        return (this.Val = int.Parse(dbVal));
    }

    public override bool SetDBVal(string value)
    {
        if (value != "")
        {
            this.dbVal = value;
            return int.TryParse(value, out this.Val);
        }

        return false;
    }

    public GlobalQueryParamInt(string low = "") : base(low) { }
}

在我的实现中,我必须声明一个基类的数组,这会在工作中抛出一个扳手。

我确信有更好的方法来做到这一点。我查看了接口,但它们也需要类型,并且由于基类型数组共享一个公共类型,我无法让泛型工作。

如果我更改上述数组,我会引入其他本质上是循环的复杂性。

实现我正在寻找或尽可能接近它的最有效方法是什么?

编辑 实现(不适用于泛型):

    GlobalQueryParam[] trail = new GlobalQueryParam[dataPos+1]; // DOESN'T WORK
    trail[0] = new GlobalQueryParamInt((this.TestParams[0].QueryLow - 1).ToString());
    trail[1] = new GlobalQueryParamInt((this.TestParams[1].QueryLow - 1).ToString());
    trail[2] = new GlobalQueryParamInt((this.TestParams[2].QueryLow - 1).ToString());
    trail[3] = new GlobalQueryParamInt((this.TestParams[3].QueryLow - 1).ToString());
    trail[4] = new GlobalQueryParamInt((this.TestParams[4].QueryLow - 1).ToString());
    trail[5] = new GlobalQueryParamInt((this.TestParams[5].QueryLow - 1).ToString());
    trail[6] = new GlobalQueryParamInt((this.TestParams[6].QueryLow - 1).ToString());
    trail[7] = new GlobalQueryParamInt((this.TestParams[7].QueryLow - 1).ToString());
4

3 回答 3

2

你想使用泛型

public abstract GlobalQueryParam{}

public abstract class GlobalQueryParam<TValue>: GlobalQueryParam where TValue : struct
{
    public readonly TValue Low;
    public TValue Val; 
    protected TValue dbVal = default(TValue);

    public TValue GetDBVal()
    {
        return  dbVal;
    }

    public abstract bool SetDBVal(TValue value);

    public abstract TValue Parse(string dbVal);

    public GlobalQueryParam(TValue low)
    {
        this.Low = low;
    }
}

public class GlobalQueryParamInt : GlobalQueryParam<int>
{

    public int Parse(string dbVal)
    {
        return (this.Val = int.Parse(dbVal));
    }

    public override bool SetDBVal(int value)
    {

        return true;
    }

    public GlobalQueryParamInt(int low = 0) : base(low) { }
}

编辑:为此创建一个基类和一个基于此帖子 泛型类型集合的集合类

于 2012-09-29T14:52:29.883 回答
1

使用您需要的方法/属性创建一个接口:

public interface IGlobalQueryParam { 

  string ToString();

  . . . 

} 

然后使用 damdum answer 中的泛型类,实现接口:

private abstract class GlobalQueryParam<TValue> : IGlobalQueryParam where TValue : struct {   
  public readonly TValue Low;   
  public TValue Val;    
  protected TValue dbVal = default(TValue);   

  public TValue GetDBVal()   
  {   
    return  dbVal;   
  }   

  public override string ToString()
  {
    return Val.ToString();
  } // ToString

  . . . implement IGlobalQueryParam . . .

}  

public class GlobalQueryParamInt : GlobalQueryParam<int> {

  . . . 
}

然后创建和使用接口的数组(或列表等):

IGlobalQueryParam[] trail = new IGlobalQueryParam[dataPos+1];
trail[0] = new GlobalQueryParamInt((this.TestParams[0].QueryLow - 1).ToString());    
trail[1] = new GlobalQueryParamInt((this.TestParams[1].QueryLow - 1).ToString());    
trail[2] = new GlobalQueryParamInt((this.TestParams[2].QueryLow - 1).ToString());    
trail[3] = new GlobalQueryParamInt((this.TestParams[3].QueryLow - 1).ToString());    
trail[4] = new GlobalQueryParamInt((this.TestParams[4].QueryLow - 1).ToString());    
trail[5] = new GlobalQueryParamInt((this.TestParams[5].QueryLow - 1).ToString());    

仍然不可能在不装箱的情况下访问每个项目的基础值(即IGlobalQueryParam返回属性object),但是可以创建接口的方法和属性,在不装箱的情况下对基础值执行所需的操作 - 例如如上例所示,将值转换为字符串。

于 2012-09-29T15:18:15.143 回答
0

最后,我恢复到我的原始代码,它将值转换和装箱到对象。泛型没有添加任何内容,因为对象继承实现了所需的类型。删除泛型后,接口什么也没有添加。

于 2012-09-30T01:00:55.713 回答