【问题标题】:Can I attach a string to a Func in C#?我可以在 C# 中将字符串附加到 Func 吗?
【发布时间】:2021-02-11 01:14:01
【问题描述】:

我希望创建命名函数:充当Func 的对象,但也有一个包含人工解释名称的字符串字段。

自然的方法是创建一个类NamedFunc<T0,T1> : Func<T0,T1> { string name; },但不幸的是 Func 不是一个类。所以我正在寻找解决方法。

最终目标是我有一个 DoMethod(MyObject 受害者, Func op) 的函数,在 DoMethod 内部我需要op 的字母数字表示(出于缓存和兼容性原因)。目前我使用op.toString().hashCode().toString(),但我想要更有意义的东西,这样我就可以真正看到哪个文件属于sum、square等,而不仅仅是看到8202589252、58809258520等。

例如,我想将类似于 NewFunc<double,double> square = new NewFunc<double,double>(x=>x*x , "square"); 的内容传递给 DoMethod,然后在调用 DoMethod(victim, square) 时,DoMethod 会以某种方式恢复该函数的字符串是“square”而不是“Func x => x * x"。同时,我希望人们也能够使用常规 Func 作为输入(不会重载方法)。

有没有可行的方法来做到这一点?还是我在寻找不可能的东西?

【问题讨论】:

  • 这对我来说不清楚,但是也许你只是想要一个 delegate/func 的字典?
  • 用字典映射函数?
  • “我在寻找几乎不可能的东西吗?” -- 取决于你到底想要什么,目前还不清楚。您绝对不能继承委托类型。但是还有很多其他的选择。参见例如Decorator Pattern。委托还存储目标方法,因此您可以从中使用方法的名称。或者,您可以将委托包装在另一个委托中,该委托将调用结果和字符串作为元组返回。或者……嗯,有很多可能性。你只需要弄清楚你真正想要什么。
  • 装饰器模式会很完美,但是根据那个维基百科页面,C#部分仍然使用继承,这在这里不可能吗?也许我没有抓住重点,但实际上我只需要装饰 Func。
  • 是的,你还是得把它包起来做装饰器。

标签: c# inheritance delegates


【解决方案1】:

虽然正如你所说,你不能使用继承,因为Func不是一个类,你仍然可以使用组合:

public class NamedFunc<T, R> {
    public string Name { get; }
    public Func<T, R> Invoke { get; }
    
    public NamedFunc(Func<T, R> function, string name) {
        Name = name;
        Invoke = function;
    }
    
    public static implicit operator Func<T, R>(NamedFunc<T, R> namedFunc) 
        => namedFunc.Invoke;
}

你将能够做你想做的事:

NamedFunc<double,double> square = new NamedFunc<double,double>(x=>x*x , "square");

要获得它的名字,只需输入square.Name。要调用它,只需执行square.Invoke(someNumber)

【讨论】:

  • 不错的解决方案;问题仍然存在……为什么?如果您查看问题,他们想在调用命名函数的同时传递对命名函数的引用吗?那么,这样做有什么好处呢?
  • @ChiefTwoPencils 知道传入的函数名称是不是很奇怪?此外,在这种情况下,它甚至不需要是方法的名称。我的理解是:任何字符串都可以,因为 OP 目前正在使用op.toString().hashCode().toString(),这似乎并不重要。 OP 似乎只想将 some 字符串关联到委托,创建一个委托字符串对。
  • 我的意思是,考虑到这个名字在他们强加给自己之前基本上没有意义,这很奇怪。我同意,将任何随机字符串放在那里可能就足够了,这再次让我想知道有什么好处。您是否不必在某个时间点变出该随机字符串才能使其有用?我的问题仍然是为什么;只是好奇。
  • @ChiefTwoPencils 我不明白你的意思。假设s.DoSomethingDoMethod,那么它的第二个参数应该是Func&lt;T, R&gt;,而不是字符串。你说的这个“秘密字符串”是什么?这里没有什么秘密吗?关于“这个名字在他们强加给自己之前基本上是没有意义的”,我想它是用于调试(除其他外),这就是为什么 OP 希望它是人类可读的,而不仅仅是op.toString().hashCode().toString()
  • 我已经添加了我想要人类可读名称而不是哈希的理由(这对我来说似乎不太相关,但我认为这是错误的),他们不能只是函数的 .toString() 因为这在文件名中是不允许的(并且您不希望 x/y 和 x*y 都映射到同一个文件,因此仅删除非法字符也不是一个可靠的选择) .不过有趣的结构,从未见过以这种方式使用的implicit operator,将对此进行研究。不管怎样,谢谢!
猜你喜欢
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 2012-02-21
相关资源
最近更新 更多