用于类型推断的通用恒等函数

发布于 2024-07-13 17:11:34 字数 869 浏览 7 评论 0原文

我想知道这是否可能,因为我的 5 分钟实验证明没有结果。

我希望它会像这样简单:

T Identity<T>(T t) { return t; }

但这无法在采用 Func 参数的通用方法上进行编译。 例如订购者。 即使指定类型参数(这正是我想避免的!),它也无法编译。

接下来我尝试了一些我认为可行的东西:

Func<T, R> MakeIdentity<T, R>()
{
  return (T t) => (R)(object)t;
}

也没有去:((这在应用类型参数时编译,再次,不是我想要的)

有人有幸做出这样的事情吗?

更新:请不要说:x => x,我知道,很明显,我要求的是一个函数,而不是一个表达式:)

更新 2:当我提到身份时,我的意思是在功能意义上,该函数只是返回您传递给它的相同对象。 它可能存在于我遇到的每种函数式语言中,但这些语言不使用静态类型。 我想知道如何使用泛型来做到这一点(如果可能的话)。 只是为了好玩!

更新 3:这是基于第二个想法的部分“解决方案”:

Expression<Func<T, T>> MakeIdentity<T>()
{
  return t => t;
}

void Foo(string[] args)
{
  var qargs = args.AsQueryable();
  var q = qargs.OrderBy(MakeIdentity<string>());
  ...
}

我认为除此之外的任何事情都是可能的。

I was wondering if it is possible, as my 5 minutes of experimentation proved fruitless.

I hoped it would be as easy as:

T Identity<T>(T t) { return t; }

But this fails to compile on generic methods taking Func parameters. Eg OrderBy. Even specifying type parameters (which is exactly what I want to avoid!), it fails to compile.

Next I tried something I thought would work:

Func<T, R> MakeIdentity<T, R>()
{
  return (T t) => (R)(object)t;
}

Also no go :( (this compiles when applying type parameters, again, not what I want)

Has anyone had luck making such a thing?

UPDATE: please dont say: x => x, I know that, it's obvious! I am asking for a function, not an expression :)

UPDATE 2: When I refer to identity, I mean in the functional sense, where the function simply returns the same object that you passed to it. It is probably in every functional language I have come across, but those do not use static typing. I am wondering how to do this (if possible) with generics. Just for fun!

UPDATE 3: Here's a partial 'solution' based on the 2nd idea:

Expression<Func<T, T>> MakeIdentity<T>()
{
  return t => t;
}

void Foo(string[] args)
{
  var qargs = args.AsQueryable();
  var q = qargs.OrderBy(MakeIdentity<string>());
  ...
}

I dont think anything more than this will be possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清风疏影 2024-07-20 17:11:34

由于宿主方法和输入方法都是通用的,类型推断将不起作用。 为此,您必须编写

myList.OrderBy<int, int>(Identity);

Or

myList.OrderBy((Func<int, int>)Identity);

Type inference will not work since host method and input method both are generic. To do this you must write

myList.OrderBy<int, int>(Identity);

Or

myList.OrderBy((Func<int, int>)Identity);
暮年 2024-07-20 17:11:34

这对我目前需要的地方很有用。

internal class IdentityFunction<TSource>
{
    public static Func<TSource, TSource> Instance
    {
        get { return x => x; }
    }
}

OrderBy(IdentityFunction<Foo>.Instance)

This works for me in places I've needed it so far.

internal class IdentityFunction<TSource>
{
    public static Func<TSource, TSource> Instance
    {
        get { return x => x; }
    }
}

OrderBy(IdentityFunction<Foo>.Instance)
雪花飘飘的天空 2024-07-20 17:11:34

您遇到的问题是 C# 中的匿名函数和方法组不参与类型推断。 必须给出显式类型。

不过,您可以做的是为匿名函数提供身份函数。 示例

Func<T> IdentityFunc1<T>(Func<T> func) { return func; }

我不完全确定您对第二个示例的理解。 你能详细说明一下吗?

The problem you're having is that anonymous functions and method groups in C# do not participate in type inference. Explicit types must be given.

What you can do though is have Identity functions for anonymous functions. Example

Func<T> IdentityFunc1<T>(Func<T> func) { return func; }

I'm not entirely sure what you're getting at with the second sample. Can you elaborate?

来日方长 2024-07-20 17:11:34

第一个选项对我有用:

public class Foo {

   public Foo(Func<MyObj, MyObj> map) {... }

}

public class Client {

   private static T Identity<T>(T t) { return t; }

   public void main() {
      var foo = new Foo(Identity);

      var c = from f in Enumerable.Range(0, 100) select Identity(f);
      c.ToList().ForEach(System.Console.Out.WriteLine);
   }
}

The first option works for me:

public class Foo {

   public Foo(Func<MyObj, MyObj> map) {... }

}

public class Client {

   private static T Identity<T>(T t) { return t; }

   public void main() {
      var foo = new Foo(Identity);

      var c = from f in Enumerable.Range(0, 100) select Identity(f);
      c.ToList().ForEach(System.Console.Out.WriteLine);
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文