小编Sco*_*ock的帖子

在深度不可变类型上进行延迟初始化需要锁吗?

如果我有一个非常不可变的类型(所有成员都是只读的,如果它们是引用类型成员,那么它们也引用了非常不可变的对象).

我想在类型上实现一个惰性初始化属性,如下所示:

private ReadOnlyCollection<SomeImmutableType> m_PropName = null;
public ReadOnlyCollection<SomeImmutableType> PropName
{
    get
    {
        if(null == m_PropName)
        {
            ReadOnlyCollection<SomeImmutableType> temp = /* do lazy init */;
            m_PropName = temp;
        }
        return m_PropName;
    }
}
Run Code Online (Sandbox Code Playgroud)

据我所知:

m_PropName = temp; 
Run Code Online (Sandbox Code Playgroud)

......是线程安全的.我并不担心两个线程同时竞争初始化,因为它很少见,从逻辑角度来看两个结果都是相同的,如果我没有,我宁愿不使用锁至.

这会有用吗?优缺点都有什么?

编辑: 谢谢你的回答.我可能会继续使用锁.但是,我很惊讶没有人提出编译器意识到临时变量是不必要的可能性,只是直接分配给m_PropName.如果是这种情况,则读取线程可能会读取尚未完成构造的对象.编译器是否会阻止这种情况?

(答案似乎表明运行时不会允许这种情况发生.)

编辑: 所以我决定使用由Joe Duffy撰写的这篇文章启发的Interlocked CompareExchange方法.

基本上:

private ReadOnlyCollection<SomeImmutableType> m_PropName = null;
public ReadOnlyCollection<SomeImmutableType> PropName
{
    get
    {
        if(null == m_PropName)
        {
            ReadOnlyCollection<SomeImmutableType> temp = /* do lazy init */;
            System.Threading.Interlocked(ref m_PropName, temp, null);
        }
        return …
Run Code Online (Sandbox Code Playgroud)

c# lazy-loading immutability lock-free

10
推荐指数
3
解决办法
2062
查看次数

在我的应用程序中使用Android 4.1(Jelly Bean)中的离线语音转文本?

Android 4.1包括离线语音输入.当您单击弹出键盘上的麦克风时,您可以看到此信息,如果您没有网络连接,它仍然有效.但是,RecognizerIntent当您想要从应用程序进行语音识别时,API 似乎仍然需要网络连接.

是否有用于从我的应用访问Android中新的离线语音输入功能的API?

android speech-recognition offline android-4.2-jelly-bean

9
推荐指数
1
解决办法
2万
查看次数

为什么这个程序在Release版本中输入if块而在Debug build中没有?

我有一些代码在Release版本和Debug版本之间表现不同.它在Debug中正常运行,但在Release中不正常.

我有一个函数返回一个ReadOnlyCollection<MyCustomClass>.一节是这样的:

        var result = new List<MyCustomClass>();
        ...
        var list1 = this.returnEmptyList();
        var list2 = this.returnListWithOneItem();
        if (list1.Count == 0 && list2.Count == 0)
        {
            functionOutVariable = string.Empty;
            return result.AsReadOnly();
        }
Run Code Online (Sandbox Code Playgroud)

出于故障排除的目的,我简化了代码并以通用方式命名变量,方法returnEmptyListreturnListWithOneItem方法如下所示:

    private List<string> returnEmptyList()
    {
        return new List<string>();
    }

    private List<string> returnListWithOneItem()
    {
        return new List<string> {"something"};
    }
Run Code Online (Sandbox Code Playgroud)

显然它永远不应该进入if块,因为它list2.Count应该始终为1,但是当我在Release版本中执行它时,它:

在此输入图像描述

因此,显然有一些优化正在进行,因为您可以看到它list1是不可访问的,并且当单步执行它时执行第416行然后立即跳转到第421行.我应该声明我的解决方案中的所有程序集都使用.NET Framework 4.6.2,并且我正在运行Visual Studio 2017版本15.3.5.

当我改变构建调试和执行这一点,执行管线416,417,和上线418它显示list1.Count为0和list2.Count1,并正确并不能进入if块.

我正在尝试制作一个测试项目来重现这一点,但我不能.我正在寻找任何方法来深究这一点.我不仅仅想要一个让它消失的修复 - …

c# compiler-optimization

9
推荐指数
1
解决办法
147
查看次数

什么是托管可扩展性框架(MEF)?

我用Google搜索并且只收到了一些关于MEF的文章.有人请简要解释一下:

  • 什么是管理可扩展性框架?
  • 它需要什么目的?
  • 我该如何开始使用它?

任何一步一步的指导都会有所帮助,谢谢!

mef definition

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

使用MVVM,ContextMenu ViewModel如何找到打开ContextMenu的ViewModel?

我正在使用MVVM将视图绑定到树中的对象.我有一个基类来实现我的树中的项目,并且该基类具有ContextMenu属性:

    public IEnumerable<IMenuItem> ContextMenu
    {
        get
        {
            return m_ContextMenu;
        }
        protected set
        {
            if (m_ContextMenu != value)
            {
                m_ContextMenu = value;
                NotifyPropertyChanged(m_ContextMenuArgs);
            }
        }
    }
    private IEnumerable<IMenuItem> m_ContextMenu = null;
    static readonly PropertyChangedEventArgs m_ContextMenuArgs =
        NotifyPropertyChangedHelper.CreateArgs<AbstractSolutionItem>(o => o.ContextMenu);
Run Code Online (Sandbox Code Playgroud)

绑定到基类(以及所有派生类)的View实现了绑定到该属性的ContextMenu:

<ContextMenu x:Name="contextMenu" ItemsSource="{Binding Path=(local:AbstractSolutionItem.ContextMenu)}"
             IsEnabled="{Binding Path=(local:AbstractSolutionItem.ContextMenuEnabled)}"
             ItemContainerStyle="{StaticResource contextMenuStyle}"/>
Run Code Online (Sandbox Code Playgroud)

菜单中的每个项目都绑定到IMenuItem对象(菜单项的ViewModel).单击菜单项时,它使用命令在基础对象上执行命令.一切都很好.

但是,一旦命令在IMenuItem类上执行,它有时需要获取用户右键单击的对象的引用以显示上下文菜单(或至少该对象的ViewModel).这是上下文菜单的重点.我应该如何将树项ViewModel的引用传递给MenuItem ViewModel?请注意,某些上下文菜单由树中的许多对象共享.

c# wpf contextmenu mvvm

8
推荐指数
2
解决办法
6632
查看次数

如何对使用VisualTreeHelper的内容进行单元测试?

我有这个静态辅助函数:

    public static DependencyObject GetParentObject(DependencyObject child)
    {
        if (child == null) return null;
        ContentElement contentElement = child as ContentElement;

        if (contentElement != null)
        {
            var parent = ContentOperations.GetParent(contentElement);
            if (parent != null) return parent;

            var fce = contentElement as FrameworkContentElement;
            return fce != null ? fce.Parent : null;
        }

        //if it's not a ContentElement, rely on VisualTreeHelper
        return VisualTreeHelper.GetParent(child);
    }
Run Code Online (Sandbox Code Playgroud)

它适用于实际应用程序,但我正在尝试为它编写一些单元测试.这是我的第一次尝试:

    [Test]
    public void GetParentObject_returns_immediate_parent()
    {
        var contentControl = new ContentControl();
        var textBox = new TextBox();

        contentControl.BeginInit();
        contentControl.Content = textBox; …
Run Code Online (Sandbox Code Playgroud)

wpf unit-testing visualtreehelper

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

在IList上调用.Last()会迭代整个列表吗?

.Last()扩展方法是否考虑了它是否被调用IList?我只是想知道这些之间是否存在显着的性能差异:

IList<int> numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

int lastNumber1 = numbers.Last();
int lastNumber2 = numbers[numbers.Count-1];
Run Code Online (Sandbox Code Playgroud)

Intuition告诉我第一个选择是O(n),但第二个是O(1).是否.Last()"聪明"足以尝试将其投射到IList

c#

8
推荐指数
2
解决办法
2433
查看次数

WPF ListView在内部布局面板周围有一个像素边框.我怎么摆脱它?

我有一个类似这样的ListView:

<ListView 
    x:Name="SeriesListView"
    SnapsToDevicePixels="True"
    ItemsSource="{Binding Items}"
    BorderBrush="Transparent" BorderThickness="0"
    Padding="0" Margin="0" 
    VerticalContentAlignment="Top"
    Background="Purple"
    LostFocus="ListView_LostFocus"
    >

    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <local:LDSeriesPanel
                SnapsToDevicePixels="True" 
                MaxWidth="{Binding ElementName=itControl,Path=ActualWidth}"
                VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
                MinHeight="{x:Static local:LDSeriesPanel.MIN_HEIGHT}" 
                MinWidth="{x:Static local:LDSeriesPanel.MIN_WIDTH}"
                Margin="0"
                Background="Aquamarine"/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>
Run Code Online (Sandbox Code Playgroud)

当它为空时,我定义的自定义面板的宽度和高度为15 x 15.我可以确认这些是运行时的实际尺寸.但是,ListView本身的尺寸为17 x 17(即面板和ListView之间的一个像素边框).

从自定义面板开始走上树,我得到以下祖先:

  • ItemsPresenter:15x15
  • ScrollViewer:15x15
  • 网格:15x15
  • ScrollViewer:15x15
  • 边境:17x17
  • ListView:17x17

如果我将ListView上的填充更改为-1,它会删除边框但会导致其他几个问题.

我希望避免重新模仿整个ListView.其他一切都很好.有没有办法可以通过一种风格删除这个像素边框?

wpf listview border

7
推荐指数
4
解决办法
9559
查看次数

有没有办法在C#中获得F#的constructor-parameters-are-automatic-immutable-private-members功能?

在F#中,构造函数参数自动保存为类中的不可变字段,而不必编写字段声明或将构造函数参数复制到构造函数中的字段.

有没有办法在C#中模仿这个功能?是否存在未来版本的C#无法具备此功能的原因(即现有语言是否存在与此功能冲突的一些基本限制)?

c# f# constructor immutability

7
推荐指数
1
解决办法
70
查看次数

如何为我的.NET应用程序启用DEP或ASLR?

我在VS2010中编写程序,构建目标是.NET 4.我相信默认情况下DEP兼容性标志是打开的.真的吗?

.NET默认情况下是否与ASLR兼容,并且默认为我的进程打开ASLR,或者我是否必须在运行时请求它?

.net security data-execution-prevention aslr

6
推荐指数
1
解决办法
4049
查看次数