3

我有一个用 T 和 K 类型编写的方法

public K Process<T,K> (IEnumerable<T> set)
{
    //do stuff to set
}

我使用 LINQ 对我的数据进行一些投影,我需要将其发送以进行处理

var dataSlice=records.Select(r => new { name = r.GetName(), id = r.GetId() });
string result =  Process <?, string>(dataSlice);

我应该指定什么?(如果可以的话)

4

3 回答 3

1

您不能直接因为dataSlice现在是匿名类型的集合,您可以尝试将类型信息排除在外:

string result = Process(dataSlice);

有时编译器可以为您推断出正确的类型,它可以节省输入并且很有用!

如果这不起作用,那么您最好不要使用匿名类型并创建适当的类型来保存数据,或者使用类似Tuple.

匿名类型很棒,但它们主要用于在 linq 查询之间穿梭数据,而不使用自定义类型。

尽管即使您可以通过编译器,您的 Process 方法也不会知道它得到了什么,因此无法从中提取元素dataSlice,因此最好按照自定义类型路由或使用Tuple前面所述的.

于 2013-04-08T21:50:58.683 回答
1

我喜欢这个简单的工具:

public static class Klass
{
    public static Klass<T> Of<T>(){ return Klass<T>.instance; }
}

public class Klass<T>
{
    public static Klass<T> instance = null;
}

现在您可以:

public K Process<T,K>(Klass<T> t, IEnumerable<K> items)
{
    ....
}

var aKey = Process(Klass.Of<string>(), mySetOfItems);
// aKey will be autotyped to a string

但请注意,这需要在 Process 方法中添加一个未使用的参数。此参数仅用于解决缺少的类型。这就是“实例”始终为空的原因。该值并不重要,重要的是这个 null 是 Klass 类型。

但是,请注意,这 100% 可以避免使用像 in 这样的显式类型参数,Process<string, ....>因为您不需要显式传递<string>类型参数。因此,所有类型参数都绑定到参数,这允许编译器自动解析匿名类型,包括 IEnumerable 的项目。

编辑:我刚刚还记得一件事,尽管更复杂和棘手。匿名类型是完全鸭式的。这意味着具有“string Key, int Value”的一个匿名类型与在其他地方创建的第二个匿名类型绝对属于同一类,后者也是“string Key, int Value”。这使您可以创建此处描述的小型辅助方法CastByExample

通常,您不能“指定”匿名类型,因为它是未命名的,并且您不能写出它的名称。但是,多亏了鸭子类型,这篇珍贵的文章展示了如何提供一个从不执行的 lambda,它返回一个“样本”匿名对象,只是为了拦截它定义的匿名类型,以便可以将类型传递给表达式链。非常特殊,但有趣的事情!

于 2013-04-08T21:55:05.677 回答
0

简短的回答是,你不能不重新设计你的方法。C# 您必须指定所有类型参数或不指定。

一种选择是将您的Process方法包装在单独的 API 中。

public class Processor<T>
{
    public K Process<K>() { ... }
}

...

public Processor<T> CreateProcessor<T> (IEnumerable<T> set)
{
    return new Processor<T>(set)
}

...

string result =  CreateProcessor(dataSlice).Process<string>();

这是一个替代方案,虽然它不太直观,IMO:

public static class Process<K>
{
    public static K From<T>(Ienumerable<T> set) { ... }
}

...

string result = Process<string>.From(dataSlice);
于 2013-04-08T21:51:35.603 回答