C# 泛型中值和引用类型的接口

C# 泛型中值和引用类型的接口,c#,generics,C#,Generics,我正在创建一个接口,该接口将由类实现,这些类将用作过滤器来创建查询字符串。每个过滤器将负责在查询中构造一个参数。用户可以定义是否包含运算符、运算符应该是什么以及值。值的表示方式取决于数据类型 布尔值:“=0” 整数:“>=2” 日期时间:“'2012-01-10'” 字符串:“='一些字符串' 您可以看到,将泛型类型同时用于引用类型和值类型存在问题。有人知道我如何对所有类型化过滤器类使用相同的接口吗这可能吗?您可以从定义中提取空值,然后将其传递到实现中。以下是一个例子: public inter

我正在创建一个接口,该接口将由类实现,这些类将用作过滤器来创建查询字符串。每个过滤器将负责在查询中构造一个参数。用户可以定义是否包含运算符、运算符应该是什么以及值。值的表示方式取决于数据类型

布尔值:“=0”

整数:“>=2”

日期时间:“'2012-01-10'”

字符串:“='一些字符串'


您可以看到,将泛型类型同时用于引用类型和值类型存在问题。有人知道我如何对所有类型化过滤器类使用相同的接口吗这可能吗?

您可以从定义中提取空值,然后将其传递到实现中。以下是一个例子:

public interface IFilter<T>
{
    T Value { get; set; }
    String Operator { get; set; }
    Boolean IncludeOperator { get; set; }
}

public abstract class Filter<T> : IFilter<T>
{
    T _value;
    String _operator = "=";
    Boolean _includeOperator = false;

    public T Value { get { return this._value; } set { this._value = value; } }

    public String Operator { get { return this._operator; } set { this._operator = value; } }

    public Boolean IncludeOperator { get { return this._includeOperator; } set { this._includeOperator = value; } }


    public override string ToString()
    {
        String param = GetValueAsString();
        if (param != null && this.IncludeOperator)
            return this.Operator + " " + param;
        else if (param != null && !this.IncludeOperator)
            return param.Trim();
        else
            return null;
    }

    protected abstract String GetValueAsString();
}

public class IntFilter : Filter<Nullable<Int64>>
{
    protected override string GetValueAsString()
    {
        // Convert the integer to a string
        return this.Value.HasValue ? this.Value.ToString() : "0";
    }
}

public class BooleanFilter : Filter<Nullable<Boolean>>
{
    protected override string GetValueAsString()
    {
        // convert the Boolean to a BIT value 1=True / 0=False
        return (this.Value.HasValue && this.Value.Value) ? "1" : "0";
    }
}

public class DateTimeFilter : Filter<Nullable<DateTime>>
{
    protected override string GetValueAsString()
    {
        // Convert the DateTime to a dateTime string in the following format - 2/27/2009 12:12:22 PM
        return (this.Value.HasValue) ? this.Value.Value.ToString("G") : null;
    }
}

public class StringFilter : Filter<String>
{
    protected override string GetValueAsString()
    {
        return string.IsNullOrWhiteSpace(Value) ? "" : Value;
    }
}
公共接口IFilter
{
T值{get;set;}
字符串运算符{get;set;}
布尔IncludeOperator{get;set;}
}
公共抽象类筛选器:IFilter
{
T_值;
字符串_运算符=“=”;
布尔值_includeOperator=false;
公共T值{get{返回此。_值;}设置{this。_值=值;}}
公共字符串运算符{get{返回此。_运算符;}设置{this。_运算符=值;}}
公共布尔IncludeOperator{get{返回此值。_IncludeOperator;}设置{this。_IncludeOperator=value;}
公共重写字符串ToString()
{
字符串参数=GetValueAsString();
if(param!=null&&this.IncludeOperator)
返回此。运算符+“”+参数;
else if(param!=null&&!this.IncludeOperator)
返回参数Trim();
其他的
返回null;
}
受保护的抽象字符串GetValueAsString();
}
公共类IntFilter:过滤器
{
受保护的重写字符串GetValueAsString()
{
//将整数转换为字符串
返回this.Value.HasValue?this.Value.ToString():“0”;
}
}
公共类布尔过滤器:过滤器
{
受保护的重写字符串GetValueAsString()
{
//将布尔值转换为位值1=True/0=False
返回(this.Value.HasValue&&this.Value.Value)?“1”:“0”;
}
}
公共类DateTimeFilter:筛选器
{
受保护的覆盖字符串GetValueAssString()
{
//将DateTime转换为以下格式的DateTime字符串-2/27/2009 12:12:22 PM
return(this.Value.HasValue)?this.Value.Value.ToString(“G”):null;
}
}
公共类StringFilter:筛选器
{
受保护的重写字符串GetValueAsString()
{
返回字符串。IsNullOrWhiteSpace(值)?“”:值;
}
}

该类型的_值真的需要为空吗?过滤器必须始终返回一个通常初始化为空的值。这可能意味着filters-ToString方法可能返回一个字符串,例如。。。“=null”。由于调用方法可能一次处理一个列表,我不希望调用方负责确定值的状态,然后做出反应。但是,老实说,我在继承和可空类型的问题上陷入了困境,我没有考虑改变我逻辑的这一部分。我来看看。谢谢您可以添加您希望ToString()的不同输出是什么吗?这可能有助于我理解你的目标是什么。这个解决方案带来的问题是,当我在GetValueAsString()方法中计算“this.Value”(值字段的属性)时,我需要使用“this.Value.HasValue”来确定值是否已设置,如果该值不是可为null的值,则该值将不可用。从抽象类中删除nullable后,我尝试使用nullable但get错误重写派生类中的字段和属性定义。(类型必须为“long”才能匹配被重写的成员“Filter.Value”)。是否有其他方法确定是否未设置值类型?因为GetValueAsString是抽象的,并且在子级中实现,在编译时您将知道实际类型是什么,因此此实现在我的测试中起作用。
public abstract class Filter<T> : IFilter<T> 
{
    Nullable<T> _value;
    String _operator = "=";
    Boolean _includeOperator = false;

    public Nullable<T> Value { get { return this._value; } set { this._value = value; } }

    public String Operator { get { return this._operator; } set { this._operator = value; } }

    public Boolean IncludeOperator { get { return this._includeOperator; } set { this._includeOperator = value; } }


    public override string ToString()
    {
        String param = GetValueAsString();
        if (param != null && this.IncludeOperator)
            return this.Operator + " " + param;
        else if (param != null && !this.IncludeOperator)
            return param.Trim();
        else
            return null;
    }

    protected abstract String GetValueAsString();
}
public class IntFilter: Filter<Int64>
{
    protected override string GetValueAsString()
    {
        // Convert the integer to a string
        return this.Value.Value.ToString();
    }
}

public class BooleanFilter : Filter<Boolean>
{
    protected override string GetValueAsString()
    {
        // convert the Boolean to a BIT value 1=True / 0=False
        return (this.Value.HasValue && this.Value.Value) ? "1" : "0";
    }
}

public class DateTimeFilter : Filter<DateTime>
{
    protected override string GetValueAsString()
    {
        // Convert the DateTime to a dateTime string in the following format - 2/27/2009 12:12:22 PM
        return (this.Value.HasValue) ? this.Value.Value.ToString("G") : null;
    }
}
public class StringFilter : Filter<String>
{
    protected override string GetValueAsString()
    {
        // Convert the integer to a string
        return this.Value.Value.ToString();
    }
}
ExecuteQuery( IFilter filter );
public interface IFilter<T>
{
    T Value { get; set; }
    String Operator { get; set; }
    Boolean IncludeOperator { get; set; }
}

public abstract class Filter<T> : IFilter<T>
{
    T _value;
    String _operator = "=";
    Boolean _includeOperator = false;

    public T Value { get { return this._value; } set { this._value = value; } }

    public String Operator { get { return this._operator; } set { this._operator = value; } }

    public Boolean IncludeOperator { get { return this._includeOperator; } set { this._includeOperator = value; } }


    public override string ToString()
    {
        String param = GetValueAsString();
        if (param != null && this.IncludeOperator)
            return this.Operator + " " + param;
        else if (param != null && !this.IncludeOperator)
            return param.Trim();
        else
            return null;
    }

    protected abstract String GetValueAsString();
}

public class IntFilter : Filter<Nullable<Int64>>
{
    protected override string GetValueAsString()
    {
        // Convert the integer to a string
        return this.Value.HasValue ? this.Value.ToString() : "0";
    }
}

public class BooleanFilter : Filter<Nullable<Boolean>>
{
    protected override string GetValueAsString()
    {
        // convert the Boolean to a BIT value 1=True / 0=False
        return (this.Value.HasValue && this.Value.Value) ? "1" : "0";
    }
}

public class DateTimeFilter : Filter<Nullable<DateTime>>
{
    protected override string GetValueAsString()
    {
        // Convert the DateTime to a dateTime string in the following format - 2/27/2009 12:12:22 PM
        return (this.Value.HasValue) ? this.Value.Value.ToString("G") : null;
    }
}

public class StringFilter : Filter<String>
{
    protected override string GetValueAsString()
    {
        return string.IsNullOrWhiteSpace(Value) ? "" : Value;
    }
}