小编jam*_*ock的帖子

为什么CLR不总是调用值类型构造函数

我有一个关于Value类型中的类型构造函数的问题.这个问题的灵感来自Jeffrey Richter在CLR中通过C#3rd ed编写的内容,他说(在第195页 - 第8章)你不应该在值类型中实际定义类型构造函数,因为有时候CLR不会调用它.

所以,例如(好吧......实际上是Jeffrey Richters的例子),即使通过查看IL,我也无法解决为什么在以下代码中没有调用类型构造函数:

internal struct SomeValType
{
    static SomeValType()
    {
        Console.WriteLine("This never gets displayed");
    }
    public Int32 _x;
}
public sealed class Program
{
    static void Main(string[] args)
    {
        SomeValType[] a = new SomeValType[10];
        a[0]._x = 123;
        Console.WriteLine(a[0]._x);     //Displays 123
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,对类型构造函数应用以下规则,我只是看不出为什么根本没有调用上面的值类型构造函数.

  1. 我可以定义一个静态值类型构造函数来设置类型的初始状态.
  2. 一个类型只能有一个构造函数 - 没有默认构造函数.
  3. 类型构造函数是隐式私有的
  4. JIT编译器检查是否已在此AppDomain中执行了类型的类型构造函数.如果不是它将调用发送到本机代码,否则它不会,因为它知道该类型已经"初始化".

所以......我无法理解为什么我看不到这个类型的数组正在被构造.

我最好的猜测是它可能是:

  1. CLR构造类型数组的方式.我原以为在创建第一个项目时会调用静态构造函数
  2. 构造函数中的代码不会初始化任何静态字段,因此会被忽略.我已经尝试在构造函数中初始化私有静态字段,但该字段仍然是默认值0 - 因此不会调用构造函数.
  3. 或者......由于公共Int32被设置,编译器以某种方式优化了构造函数调用 - 但这是一个模糊的猜测!

最佳实践等帮助,我只是对它非常感兴趣,因为我希望能够亲眼看到它为什么不被调用.

编辑:我在下面添加了我自己的问题的答案,只是引用杰弗里里希特所说的.

如果有人有任何想法,那将是辉煌的.非常感谢,詹姆斯

c# clr struct static-constructor typeinitializer

37
推荐指数
2
解决办法
1660
查看次数

要在Select()查询中使用的Lambda表达式

我正在尝试构建一个lambda表达式,包含两个赋值(如下图所示),然后我可以传递给Queryable.Select()方法.

我试图将一个字符串变量传递给一个方法,然后使用该变量来构建lambda表达式,以便我可以在LINQ Select查询中使用它.

我的理由是我有一个包含许多列名的SQL Server数据源,我正在创建一个图表应用程序,允许用户通过输入列名来选择他们想要在列中查看的实际数据列.我的图表的y轴,x轴始终是DateTime.因此,他们基本上可以根据DateTime值选择他们绘制的数据(它是数据仓库类型的应用程序).

例如,我有一个类来存储检索到的数据,因此用作以下图表来源:

public class AnalysisChartSource
{
    public DateTime Invoicedate { get; set; }
    public Decimal yValue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我(纯实验)使用String值为Where子句构建了一个表达式树,并且工作正常:

public void GetData(String yAxis)
{
    using (DataClasses1DataContext db = new DataClasses1DataContext())
    {
        var data = this.FunctionOne().AsQueryable<AnalysisChartSource>();
        //just to get some temp data in....

        ParameterExpression pe = Expression.Parameter(typeof(AnalysisChartSource), "p");
        Expression left = Expression.MakeMemberAccess(pe,
                                                typeof(AnalysisChartSource).GetProperty(yAxis));
        Expression right = Expression.Constant((Decimal)16);
        Expression e2 = Expression.LessThan(left, right);
        Expression expNew = Expression.New(typeof(AnalysisChartSource));

        LambdaExpression le = Expression.Lambda(left, pe);

        MethodCallExpression whereCall = …
Run Code Online (Sandbox Code Playgroud)

c# lambda expression-trees

8
推荐指数
1
解决办法
4702
查看次数

MEF,EntLib和Prism之间的差异

我有一个相对基本的问题,但实际上只需要一些清晰度,我一直在使用Prism(复合应用指南)在C#中创建一个WPF MVVM桌面应用程序,这一点我都清楚(或者我认为)沿着与IoC和基于模块的架构等.同时我开始使用MEF并意识到两者之间存在一种灰色区域(我已经发现并阅读了许多关于在IoC容器中托管MEF扩展的文章/博客类似.

但是......最近我开始关注企业库5,这是什么导致了我的困惑.它们在哪里组合在一起?所以Prism使用DI和基于模块的架构...... EntLib使用Di和应用程序块类型架构...... MEF根本不使用DI?这是否意味着EntLib和Prism是完全独立的架构方法,或者一个是另一个的子集?MEF也可以和/两者一起使用吗?

任何解释都是最受欢迎的.

非常感谢

enterprise-library prism mef

5
推荐指数
1
解决办法
2151
查看次数