我正在寻找一种方法来否定用于过滤IQueryable序列的表达式.
所以,我有类似的东西:
Expression<Func<T, bool>> expression = (x => true);
Run Code Online (Sandbox Code Playgroud)
现在我希望创建一个会导致屈服的表达式(x => false)- 所以我基本上想要否定它expression.
我发现自己的工作方法是这样的:
var negatedExpression =
Expression.Lambda<Func<T, bool>> (Expression.Not(expression.Body),
expression.Parameters[0])));
Run Code Online (Sandbox Code Playgroud)
但我几乎肯定有更好的方法 - 你能帮助我吗?(Not(expression)可能是这样的).
C#4,为简化COM互操作,允许调用者在COM接口中省略ref参数前面的ref关键字.
我很惊讶今天看到这也适用于扩展COM接口的扩展方法.请参阅以下内容,编译代码:
using System;
using System.Runtime.InteropServices;
[ComImport, Guid ("cb4ac859-0589-483e-934d-b27845d5fe74")]
interface IFoo {
}
static class Program {
public static void Bar (this IFoo self, ref Guid id)
{
id = Guid.NewGuid ();
}
static void Main ()
{
Foo (null);
}
static void Foo (IFoo o)
{
Guid g = Guid.NewGuid ();
Console.WriteLine (g);
// note that g is passed as is, and not as ref g
o.Bar (g);
Console.WriteLine (g);
}
}
Run Code Online (Sandbox Code Playgroud)
我没有在规范中找到任何解释这种行为的内容.
我的感觉是COM接口之外的代码,即使它是扩展COM接口的扩展方法,也应该遵循常规的C#规则,并强制使用ref关键字.因此我在连接上提交了一个错误.并不是说我认为这将被修复,即使它被认为是一个bug,已经有代码依赖于此.
错误?不是一个bug?
它是有效的(即它编译并运行)将属性放在类或方法的泛型参数上:
public class MyClass<[My] T>
{
private void MyMethod<[My] T>()
{}
}
public class MyAttribute : Attribute
{}
Run Code Online (Sandbox Code Playgroud)
我从来没有见过这种情况,并且正在努力想出一个你为什么要这么做的理由.
它只是语言规范的怪癖/副作用,还是有一个有效/有用的理由将属性置于这个位置?
每个.net开发人员都知道属性的概念.粗略的99.99%,它只是一个元数据粘合在一起的两个方法,一个吸气剂和一个设定器.
通常使用add,remove和invoke方法对事件也是如此.
ECMA-335描述了一种"其他"方法语义,适用于属性或事件.从概念上讲,财产或事件可能有多种"其他"方法.
今天是我用"其他"方法偶然发现房产的第一天.当然,它必须与COM有关.EnvDTE程序集中的EnvDTE.Property接口(用于向Visual Studio编写插件)包含一个定义如下的属性:
.property object Value()
{
.custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 00 00 00 00 00 00 )
.get instance object EnvDTE.Property::get_Value()
.other instance void EnvDTE.Property::let_Value(object)
.set instance void EnvDTE.Property::set_Value(object)
}
Run Code Online (Sandbox Code Playgroud)
将let_Value定义为:
.method public hidebysig newslot specialname abstract virtual
instance void let_Value([in] object marshal( struct) lppvReturn) runtime managed internalcall
{
.custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 00 00 00 00 00 00 )
}
Run Code Online (Sandbox Code Playgroud)
显然,VB.NET之前的VBScript和VB版本可以使用Let关键字定义属性.并且Let与Set具有相同的签名.我觉得这里有关系.
但有没有人知道这个属性是如何用EnvDTE编写的语言声明的?我怎么能用相同的模式创建一个程序集(不使用ilasm,这太容易了)?还有人遇到类似的财产吗?
有没有人见过其他"其他"属性,可能与这个属性有不同的语义?如果是的话,他们习惯了什么?
我正在使用AssembliyDefinition.ReadAssembly加载两个程序集
在AssemblyA中,我定义了ClassA.
在AssemblyB中,我定义了ClassB:ClassA.
当我检查ClassB的TypeDefinition.BaseType时,我得到它的Module是AssemblyB.
我希望它的模块是AssemblyA,因为ClassB的基类型是ClassA,它在AssemblyA中定义.
这显示为我的错误,因为当我尝试执行classB.BaseType.Resolve()时,我得到一个错误,这可能发生,因为它在错误的程序集中搜索ClassA.
任何人的想法?
谢谢
c# ×4
.net ×2
attributes ×1
c#-4.0 ×1
cil ×1
csc ×1
expression ×1
generics ×1
mono.cecil ×1
negate ×1