1

我在 ASP.NET 网页中有一个 GridView 和一个 DetailsView,我需要提取其中一个或另一个以获取它的信息,并且为此创建了一个函数。GridView 和 DetailsView 都有一个名为 Rows 的属性,这是我需要在我的函数中使用的。

所以在代码中我有如下内容:

// Where dv is DetailsView and gv is GridView
if(someBool) 
   foo(dv); 
else
   foo(gv);

其中 foo 如下所示:

void foo(SomeBaseClassOrInterface dv) {
    foreach(var row in dv.Rows) {
       Use(row.Cells[2].Text); // Simply read each row
     }
}

我认为我可以使用同一个函数,而不是创建两个不同的函数,因为 DetailsViewRowCollection 和 GridViewRowCollection 的操作是彼此的镜像。问题是我没有看到有共享 Rows 属性的基类。

我尝试创建两个继承自 DetailsView 和 GridView 的类,并简单地使用它们父级的 Row 属性,它们都实现了一个接口,然后我在我的主代码中使用该接口,但这似乎不起作用。原因是 DetailsView 和 GridView 的 Rows 的返回类型不同,这两种返回类型都继承自 IEnumerable,但任何实现该接口的类都需要使其 Row 属性也返回一个 IEnumerable,使用泛型绕过此限制,但随后在我的调用代码中失败它抱怨我实现 GridView 和 DetailsView 的对象无法转换为 Interface 类型。

我觉得我缺少一个非常简单的解决方案。也许在这种情况下复制代码可能更容易?

我正在尝试找到一种理想地避免重复代码的好方法。

谢谢

4

3 回答 3

1

您可以定义接受 IEnumerable 的函数,并且因为 GridViewRow 和 DetailsViewRow 派生自 TableRow,您可以使用 TableRow 作为枚举变量:

void foo(IEnumerable enumerable) {
    foreach(TableRow row in enumerable) {
       Use(row.Cells[2].Text); // Simply read each row
     }
}

您必须将 Rows 传递给函数:

if(someBool) 
   foo(dv.Rows); 
else
   foo(gv.Rows);
于 2013-07-29T23:58:53.230 回答
0

关于什么:

if(someBool) 
   Use(dv.SelectMany(x => x.Rows).SelectMany(x => x.Cells[2].Text));
else
   Use(gv.SelectMany(x => x.Rows).SelectMany(x => x.Cells[2].Text));

并更改Use()方法以接受一个IEnumerable<string>而不是单个字符串。

看起来仍然违反 DRY,但您已删除该foo()方法。

于 2013-07-29T23:16:51.677 回答
0

一个选项 - 创建“提取器”界面,该界面将处理从其中任何一个获取信息。添加 2 个实现 - 一个用于GridView,另一个用于DetailsView.

class CellType
{
   // some fields that are interesting like
   public string Text {get;set;}
}

class Row {
   public List<CellType> Cells {get;set}
}

interface IRowExtractor
{ 
     IEnumerable<Row> Rows {get};
}

class GVRowExtractor : IRowExtractor
{
   List<Rows> rows;
   public GVRowExtractor(GridView gv)
   {
        // fill Rows from gv
   }
   public IEnumerable<Row> Rows {get {return rows;}};
}

class DVRowExtractor : IRowExtractor ....

void foo(IRowExtractor dv) {
  foreach(var row in dv.Rows) {
     Use(row.Cells[2].Text); // Simply read each row
 }
}

用法:

foo(new DVRowExtractor(dv));
于 2013-07-29T23:20:04.083 回答