C# 如何强制委托类型不保存任何信息?

C# 如何强制委托类型不保存任何信息?,c#,delegates,C#,Delegates,我正在设计一个与Linq非常相似的API(它是一个作用于更复杂对象的Linq),我有一些客户机开发人员并不完全理解它背后的原理。我想阻止他们做一些事情,以便他们的代码更符合API的所有内容。因此,对于示例,我将只参考Linq 简而言之,我在客户机代码中看到的类似于: IEnumerable<double> xlist; IEnumerable<double> ylist; var zlist = xlist.Select( (x,i) => x + ylist.El

我正在设计一个与Linq非常相似的API(它是一个作用于更复杂对象的Linq),我有一些客户机开发人员并不完全理解它背后的原理。我想阻止他们做一些事情,以便他们的代码更符合API的所有内容。因此,对于示例,我将只参考Linq

简而言之,我在客户机代码中看到的类似于:

IEnumerable<double> xlist;
IEnumerable<double> ylist;
var zlist = xlist.Select( (x,i) => x + ylist.ElementAt(i) );
所以在考虑了它之后,我认为我真正想要的API是防止客户端将数据“注入”到委托类型中。换句话说,我想定义扩展方法,例如:

IEnumerable<TResult> MySelect<TSource, TResult>(
                                this IEnumerable<TSource> source,
                                StaticFunc<TSource, int, TResult> selector)
IEnumerable MySelect(
这是一个数不清的来源,
StaticFunc选择器)
其中StaticFunc是一种委托类型,它不包含任何数据(或者最多只包含静态上下文数据)

有人能想出办法吗

我正在设计一个与Linq非常相似的API(它是一个作用于更复杂对象的Linq),我有一些客户机开发人员并不完全理解它背后的原理。我想阻止他们做一些事情,以便他们的代码更符合API的所有内容

听起来你真正需要的是代码审查和教育,而不是工具。当然,语言中没有任何东西可以确保开发人员没有这样做——依我看,您甚至不想这样做。例如,您的规则将禁止:

public IQueryable<Person> FindUsersByFirstName(string firstName)
{
    return repository.Users.Where(user => user.FirstName == firstName);
}
public IQueryable FindUsersByFirstName(字符串firstName)
{
返回repository.Users.Where(user=>user.FirstName==FirstName);
}

毕竟,
firstName
是上下文数据。。。但这与LINQ完全一致。

您可以尝试使用而不是委托。您将能够检查传递到代码中的内容,这与委托不同

我知道在lambda表达式中引用外部变量的能力在许多情况下都非常有用。也就是说,当你想阻止人们把车停在你的花园里时,关门总比标志好。@d--b:我不知道这个比喻有什么关系,但我知道,我宁愿花时间审查代码并与同事交谈,也不愿试图阻止他们做一些有害的事情,因为这样做也会阻止他们做一些有用和常见的事情。也许你应该坚持使用C#2,然后结束它。。。(当然,这不会阻止匿名方法。)好的,我知道你的答案是“没有办法做到这一点,所以你应该做代码检查和教育”。这就是我要做的。我只是想看看.Net framework中是否有一种类型描述了“指向静态方法的委托”,以便限制我的用户。约束开发人员可以针对API做什么的能力很重要。这和sealed关键字或List.AsReadOnly()存在的原因是一样的,不是吗?@d--b:不,我不是这么说的。我是说,即使你可以很容易地做到这一点,你也不应该。这简直太严格了。我完全同意能够约束用户是很重要的,但只有在合理的情况下,我相信你把孩子和洗澡水一起扔掉了。您可以在执行时检查委托的调用列表中是否只有一个操作,它是否引用了静态方法-但这不是编译时检查,基本上是一个坏主意。啊,好吧,我会再考虑一下,也许有一些事情我没有完全掌握。无论如何,谢谢你的回答这是个好主意,但我考虑的是编译时而不是运行时。
public IQueryable<Person> FindUsersByFirstName(string firstName)
{
    return repository.Users.Where(user => user.FirstName == firstName);
}