C# 为.Field编写通用方法<;T>;()在Linq to数据集中

C# 为.Field编写通用方法<;T>;()在Linq to数据集中,c#,datatable,linq-to-objects,C#,Datatable,Linq To Objects,我一直在尝试编写一个可重用的通用方法来查找数据表。到目前为止,我所拥有的: private static IEnumerable<DataRow> GetRow<FType>(string Tablename, string Fieldname, FType Match) { var result = from row in dataSet.Tables[Tablename].AsEnumerable() where r

我一直在尝试编写一个可重用的通用方法来查找
数据表
。到目前为止,我所拥有的:

private static IEnumerable<DataRow> GetRow<FType>(string Tablename, 
    string Fieldname, FType Match)
{
    var result = from row in dataSet.Tables[Tablename].AsEnumerable()
                 where row.Field<FType>(Fieldname) == Match
                 select row;

    return result;
}
private静态IEnumerable GetRow(字符串Tablename,
字符串字段名,FType匹配)
{
var result=来自dataSet.Tables[Tablename].AsEnumerable()中的行
其中row.Field(Fieldname)=匹配
选择行;
返回结果;
}
但是,我们不喜欢
行.Field(Fieldname)=Match


我该怎么做才能解决这个问题?我得到:运算符“==”不能应用于FType和FType。

使用.Equals()应该可以做到这一点。另一个选项是使用.Equals()传入IComparer或委托比较器进行自定义比较。另一个选项是传入IComparer或委托比较器进行自定义比较

您可以使用运算符重载:

public static bool operator ==(FType a, FType b)
{
    // Your code
    // Check here if A and B are equal
}

您可以使用运算符重载:

public static bool operator ==(FType a, FType b)
{
    // Your code
    // Check here if A and B are equal
}

==Match
替换为
.Equals(Match)
,您应该表现良好。我抛出了一个空检查,以防值可能为空

private static IEnumerable<DataRow> GetRow<FType>(string Tablename, string Fieldname, FType Match)
{
    var result = from row in dataSet.Tables[Tablename].AsEnumerable()
                 where row.Field<FType>(Fieldname) != null
                 && row.Field<FType>(Fieldname).Equals(Match)
                 select row;

    return result;
} 
private静态IEnumerable GetRow(字符串表名、字符串字段名、FType匹配)
{
var result=来自dataSet.Tables[Tablename].AsEnumerable()中的行
其中row.Field(Fieldname)!=null
&&row.Field(Fieldname).Equals(匹配)
选择行;
返回结果;
} 

==Match
替换为
.Equals(Match)
,你应该表现良好。我抛出了一个空检查,以防值可能为空

private static IEnumerable<DataRow> GetRow<FType>(string Tablename, string Fieldname, FType Match)
{
    var result = from row in dataSet.Tables[Tablename].AsEnumerable()
                 where row.Field<FType>(Fieldname) != null
                 && row.Field<FType>(Fieldname).Equals(Match)
                 select row;

    return result;
} 
private静态IEnumerable GetRow(字符串表名、字符串字段名、FType匹配)
{
var result=来自dataSet.Tables[Tablename].AsEnumerable()中的行
其中row.Field(Fieldname)!=null
&&row.Field(Fieldname).Equals(匹配)
选择行;
返回结果;
} 

我会使用
IEqualityComparer
进行相等性检查。您还可以添加一个可以显式指定比较器的重载

private static IEnumerable<DataRow> GetRow<FType>(string Tablename, string Fieldname, FType match)
{
    IEqualityComparer<FType> comp = EqualityComparer<TField>.Default;
    return dataSet.Tables[Tablename]
        .AsEnumerable()
        .Where(comp.Equals(row.Field<FType>(Fieldname), match));
}
private静态IEnumerable GetRow(字符串表名、字符串字段名、FType匹配)
{
IEqualityComparer comp=EqualityComparer.Default;
返回dataSet.Tables[表名]
.可计算的()
其中(comp.Equals(行字段(字段名),匹配));
}

我会使用
IEqualityComparer
进行相等性检查。您还可以添加一个可以显式指定比较器的重载

private static IEnumerable<DataRow> GetRow<FType>(string Tablename, string Fieldname, FType match)
{
    IEqualityComparer<FType> comp = EqualityComparer<TField>.Default;
    return dataSet.Tables[Tablename]
        .AsEnumerable()
        .Where(comp.Equals(row.Field<FType>(Fieldname), match));
}
private静态IEnumerable GetRow(字符串表名、字符串字段名、FType匹配)
{
IEqualityComparer comp=EqualityComparer.Default;
返回dataSet.Tables[表名]
.可计算的()
其中(comp.Equals(行字段(字段名),匹配));
}

很好的建议,但是
.Equals
意味着您必须考虑圆点左侧的空值,但是我们不知道
FType
是引用类型还是值类型,以及它是否可以为空值。您可以通过提供两个具有不同泛型约束的独立方法来解决这个问题,但这让我觉得很难看。@Alex,这两个不同的方法需要的区别不仅仅是约束,因为它们不是签名的一部分。但是您可以在单个方法中安全地包含空检查<代码>行位置字段(字段名)!=null&[其他标准]很好的建议,但是
.Equals
意味着您必须考虑点左侧的null,但是我们不知道
FType
是引用类型还是值类型,以及它是否可以为null。您可以通过提供两个具有不同泛型约束的独立方法来解决这个问题,但这让我觉得很难看。@Alex,这两个不同的方法需要的区别不仅仅是约束,因为它们不是签名的一部分。但是您可以在单个方法中安全地包含空检查<代码>行位置字段(字段名)!=空值&[其他条件]+1用于包含空值检查。奇怪的是,
=
可以,但不能使用
==
+1包含空检查。奇怪的是,
=可以,但不能使用
==