简体   繁体   English

我可以从扩展方法返回不同的类型

[英]Can I Return Different Types From An Extension Method

I basically want to write a DataTable extension method to hide a generalized LINQ query. 我基本上想要编写一个DataTable扩展方法来隐藏一个通用的LINQ查询。 Lets say I have the DataTables below: 假设我有以下DataTables:

DataTable1

[ID]    [NameOfThing]    [DateOfThing]
1       'FirstName'      1/2/34
2       'SecondName'     5/6/78

DataTable2

[SomeFieldId]    [NumberOfItems]
3                934
4                20393

I want to be able to call an extension method like string aString = DataTable1.GetDataItem(1,"ID","NameOfThing") 我想能够调用一个扩展方法,如string aString = DataTable1.GetDataItem(1,"ID","NameOfThing")
or 要么
int anInt = DataTable2.GetDataItem(3,"SomeFieldId","NumberOfItems")

I think my extension method would look something like this: 我认为我的扩展方法看起来像这样:

public static var GetDataItem(this DataTable dTable, int idToMatch
                          ,string fieldToMatchIdTo, string fieldToReturn)  
{  
    DataRow [] results = dTable.AsEnumerable()  
          .Where(r => r.Field`<int>`(fieldToMatchTo) == idToMatch).ToArray();  
    return (var)results[0][fieldToReturn];  
}

I know there's a lot missing here (casting to var seems dubious) but hopefully I captured the idea of what I'm trying to do. 我知道这里有很多缺失(转换为var似乎很可疑)但希望我抓住了我想要做的事情的想法。 Is it possible, or are there any other good alternatives? 有可能,还是有其他好的选择? I could write an extension method for each return type I suppose but I'm hoping there's a more generalized approach out there. 我可以为每个返回类型编写一个扩展方法,但我希望有一个更通用的方法。

You can just make it generic: 你可以把它变成通用的:

public static T GetDataItem<T>(this DataTable dTable, int idToMatch, string fieldToMatchIdTo, string fieldToReturn)  
{  
    DataRow results = dTable.AsEnumerable()  
          .Where(r => r.Field<int>(fieldToMatchTo) == idToMatch).ToArray();  
    return (T)results[0][fieldToReturn];  
}

which you can call like: 您可以这样称呼:

int anInt = DataTable2.GetDataItem<int>(3,"SomeFieldId","NumberOfItems");

if for some reason you don't know the type of the returned value, you'll have to just return object. 如果由于某种原因你不知道返回值的类型,你将只需要返回对象。

Note that since you expect at least one row to match you can use First instead of Where : 请注意,由于您希望至少有一行匹配,因此可以使用First而不是Where

DataRow row = dTable.AsEnumerable().First(r => r.Field<int>(fieldToMatchTo) == idToMatch);
return (T)row[fieldToReturn];

You can change your method like this to use generics 您可以像这样更改方法以使用泛型

 public static T GetDataItem<T>(this DataTable dTable, int idToMatch
                      ,string fieldToMatchIdTo, string fieldToReturn)  
 {  
DataRow results = dTable.AsEnumerable()  
      .Where(r => r.Field`<int>`(fieldToMatchTo) == idToMatch).ToArray();  
return (T)results[0][fieldToReturn];  
}

and your calls will be like this 你的电话会是这样的

int result = DataTable2.GetDataItem<int>(3,"SomeFieldId","NumberOfItems")
string aString = DataTable1.GetDataItem<string>(1,"ID","NameOfThing")

I would probably make a generic method like this: 我可能会做一个像这样的通用方法:

public static T GetDataItem<T>(this DataTable dTable, int idToMatch, 
                               string fieldToMatchIdTo, string fieldToReturn)  
{  
    var result = dTable.AsEnumerable()  
                       .Where(r => r.Field<int>(fieldToMatchTo) == idToMatch)
                       .FirstOrDefault();

    if (result == null)
    {
        return default(T);
    }
    else
    {
        return result.Field<T>(fieldToReturn);
    }
}

Usage: 用法:

var anInt = DataTable2.GetDataItem<int>(3,"SomeFieldId","NumberOfItems")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM