小编Ani*_*Ani的帖子

MethodImplOptions.InternalCall有什么意义?

BCL中的许多方法都标有 [MethodImpl(MethodImplOptions.InternalCall)]属性.这表明 "方法是在公共语言运行时本身内实现的".

以这种方式设计框架的重点是指定了运行时将被强制实现的显式CIL指令?最终,该属性正在为运行时创建合同义务,但在某种程度上,我觉得这种方式令人困惑,而且不是很明显.

例如,Math.Pow本来可以用这种方式编写(请原谅我非正式的C#+ IL和IL本身,如果它不好的话;这只是一个解释我的观点的样本):

public static double Pow(double x, double y)
{
    ldarg.0
    ldarg.1
    pow // Dedicated CIL instruction
    ret
}
Run Code Online (Sandbox Code Playgroud)

而不是当前的方式:

[MethodImpl(MethodImplOptions.InternalCall)]
public static double Pow(double x, double y);
Run Code Online (Sandbox Code Playgroud)

为什么MethodImplOptions.InternalCall存在?

.net clr cil framework-design

30
推荐指数
2
解决办法
9342
查看次数

是否可以从另一个线程观察部分构造的对象?

我经常听说在.NET 2.0内存模型中,写入始终使用释放围栏.这是真的?这是否意味着即使没有明确的内存屏障或锁定,也不可能在不同于创建它的线程上观察部分构造的对象(仅考虑引用类型)?我显然排除了构造函数泄漏this引用的情况.

例如,假设我们有不可变的引用类型:

public class Person
{
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}
Run Code Online (Sandbox Code Playgroud)

是否可以使用以下代码观察除"John 20"和"Jack 21"之外的任何输出,例如"null 20"或"Jack 0"?

// We could make this volatile to freshen the read, but I don't want
// to complicate the core of the question.
private Person person;

private void Thread1()
{
    while (true)
    {
        var personCopy = person; …
Run Code Online (Sandbox Code Playgroud)

.net c# multithreading memory-model thread-safety

27
推荐指数
1
解决办法
1125
查看次数

在对象初始值设定项中分配事件

为什么不能在C#中的对象初始值设定项中分配事件和属性?这样做似乎很自然.

var myObject = new MyClass()
     {
        Property = value,
        Event1 = actor,
        // or
        Event2 += actor
     };  
Run Code Online (Sandbox Code Playgroud)

还是有一些我不知道的技巧?

.net c# events delegates object-initializers

21
推荐指数
2
解决办法
5368
查看次数

如何将委托转换为相同的委托?

委托有两种描述:第一种是在第三方程序集中:

public delegate void ClickMenuItem (object sender, EventArgs e)
Run Code Online (Sandbox Code Playgroud)

二,标准:

public delegate void EventHandler (object sender, EventArgs e);
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个接收EventHandler类型参数的方法,并使用参数ClickMenuItem调用第三方库.

如何将ClickMenuItem转换为EventHandler?

c# delegates type-conversion

18
推荐指数
3
解决办法
5858
查看次数

为什么通过继承类型访问静态成员是有用的?

我很高兴C#不允许你访问静态成员,就像'他们是实例成员一样.这避免了Java中的常见错误:

Thread t = new Thread(..);
t.sleep(..); //Probably doesn't do what the programmer intended.
Run Code Online (Sandbox Code Playgroud)

在另一方面,它不会让你访问"到"派生类型的静态成员.除了运算符(它可以让你免于编写演员表),我无法想到任何实际上有用的情况.事实上,它积极鼓励错误,例如:

// Nasty surprises ahead - won't throw; does something unintended:
// Creates a HttpWebRequest instead.
var ftpRequest = FtpWebRequest.Create(@"http://www.stackoverflow.com");

// Something seriously wrong here.
var areRefEqual = Dictionary<string, int>.ReferenceEquals(dict1, dict2);
Run Code Online (Sandbox Code Playgroud)

我个人保持了承诺,当我通过陌生的API搜索我的方式过类似的错误(我记得开始了与表达式目录树,我打BinaryExpression.在编辑器中,并想知道为什么地球上的智能感知人给我MakeUnary作为一个选项).

在我的(短视)意见中,此功能:

  1. 不减少冗长; 程序员必须以某种方式指定类型名称(当访问当前类型的继承静态成员时,不包括运算符和大小写).
  2. 鼓励上面提到的错误/误导性代码.
  3. 可以向程序员建议C#中的静态方法表现出某种"多态性",而不是.
  4. (次要)在重新编译时引入'沉默',可能是无意的重新绑定可能性.

(国际海事组织,运营商是一个特殊情况,值得他们自己讨论.)

鉴于C#通常是"成功的一块"语言,为什么这个功能存在?我看不到它的好处(除了'可发现',它总是可以在IDE中解决),但我看到很多问题.

c# inheritance static language-design

18
推荐指数
1
解决办法
1213
查看次数

有效地消除.NET表达式树中的常见子表达式

我编写了一个DSL和一个从中生成.NET表达式树的编译器.树中的所有表达式都是无副作用的,并且表达式保证是"非语句"表达式(没有本地,循环,块等).(编辑:树可能包括文字,属性访问,标准操作符和函数调用 - 这可能正在做一些奇特的事情,如内部的memoization,但外部副作用是免费的).

现在我想对它执行"Common sub-expression elimination"优化.

例如,给定一个对应于C#lambda的树:

foo =>      (foo.Bar * 5 + foo.Baz * 2 > 7) 
         || (foo.Bar * 5 + foo.Baz * 2 < 3)  
         || (foo.Bar * 5 + 3 == foo.Xyz)
Run Code Online (Sandbox Code Playgroud)

...我想生成树等价的(忽略一些短路语义被忽略的事实):

foo =>
{
     var local1 = foo.Bar * 5;

     // Notice that this local depends on the first one.        
     var local2 = local1 + foo.Baz * 2; 

     // Notice that no unnecessary locals have been generated.
     return local2 > 7 || …
Run Code Online (Sandbox Code Playgroud)

.net c# algorithm optimization expression-trees

17
推荐指数
2
解决办法
1282
查看次数

Expression.Bind() - 它实际上做了什么?

所以我最近一直在玩动态构建表达式树,并遇到了这种方法,这看起来有点奇怪.起初,在经常编写代码之后,我认为"哦,这正是我需要的"

var left = member is FieldInfo ? Expression.Field(instance, (FieldInfo)member) : Expression.Property(instance, (PropertyInfo)member);
var right = ...
var assign = Expression.Assign(left, right);
Run Code Online (Sandbox Code Playgroud)

是的,我知道有Expression.PropertyOrField()呼叫,但它确实往返于反射,以便按名称查找成员,我通常已经拥有MemberInfo实例.

所以无论如何,我认为Expression.Bind()对我有用,但它做了一些我不太懂的事情.给出以下代码:

void Main()
{
    var m = typeof(Foo).GetField("Bar");
    Expression.Bind(m, Expression.Constant("")).Dump();
}

public class Foo
{
    public string Bar;
}
Run Code Online (Sandbox Code Playgroud)

它产生MemberAssignment表达Bar = "".但是没有实例也没有静态引用.我如何将这个表达式应用于和实例Foo?我找不到任何使用此方法的示例.

.net c# reflection expression expression-trees

16
推荐指数
1
解决办法
4353
查看次数

如何命名字典?

Dictionary<TKey, TValue>在.NET中是否有任何关于命名关联数组(例如)的约定/指南?

例如,有更好的方法来命名dict:

var dict = new Dictionary<Foo, Bar>();
Run Code Online (Sandbox Code Playgroud)

我用过/看过的一些名字:

foosToBars
mapFromFooToBar
barsByFoo
barsForFoos
Run Code Online (Sandbox Code Playgroud)

我还看到BCL中的某些类型选择"更好"的发音名称,这些名称并不直接揭示键和值应该表示的内容,例如在此方法中.

多图(例如ILookup<TKey, TElement>)如何?

编辑:

也许我的例子稍差; 我并不是要专注于键和值的类型.

如果它是这样的:

// key = Name of person, value = Age of person
var dict = new Dictionary<string, int>();
Run Code Online (Sandbox Code Playgroud)

样本更新为:

namesToAges
mapFromNameToAge
agesByName
agesForNames
Run Code Online (Sandbox Code Playgroud)

.net c# dictionary coding-style naming-conventions

15
推荐指数
1
解决办法
5252
查看次数

编译C#lambda表达性能与重叠

考虑这个课程:

/// <summary>
/// Dummy implementation of a parser for the purpose of the test
/// </summary>
class Parser
{
    public List<T> ReadList<T>(Func<T> readFunctor)
    {
        return Enumerable.Range(0, 10).Select(i => readFunctor()).ToList();
    }

    public int ReadInt32()
    {
        return 12;
    }

    public string ReadString()
    {
        return "string";
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用已编译的lambda表达式树生成以下调用:

Parser parser = new Parser();
List<int> list = parser.ReadList(parser.ReadInt32);
Run Code Online (Sandbox Code Playgroud)

但是,表现并不完全相同......

class Program
{
    private const int MAX = 1000000;

    static void Main(string[] args)
    {
        DirectCall();
        LambdaCall();
        CompiledLambdaCall();
    }

    static void DirectCall()
    {
        Parser …
Run Code Online (Sandbox Code Playgroud)

c# linq lambda expression-trees

15
推荐指数
2
解决办法
1837
查看次数

'System.DateTime'类型的表达式不能用于返回类型'System.Object'

我创建了一个表达式,我正在使用它进行排序工作正常,直到我遇到一个DateTime字段,我得到以下错误(在第二行):

'System.DateTime'类型的表达式不能用于返回类型'System.Object'

这是我的代码:

ParameterExpression param = Expression.Parameter(typeof(MyEntity), "x");

Expression<Func<MyEntity, object>> sortExpression =
    Expression.Lambda<Func<AMyEntity, object>>(
        Expression.Property(param, sortKey), param);
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮忙吗?

c# linq expression expression-trees

15
推荐指数
2
解决办法
8590
查看次数