【问题标题】:Accessing non-static member in c# Lazy *without* using default constructor在 c# Lazy *without* 中使用默认构造函数访问非静态成员
【发布时间】:2021-10-05 14:32:09
【问题描述】:

我想为我的班级添加一个Lazy。要在Lazy 的初始化方法中访问非静态成员,最佳实践方法(参见https://stackoverflow.com/a/14029443/10406502)是在默认构造函数中定义Lazy。这在我的项目中是不可能的,因为它是一个部分类,并且默认构造函数已经由一些自动生成的代码(实体框架)定义。

有没有办法使用Lazy 访问非静态类成员而不在默认构造函数中实现它?

【问题讨论】:

  • private Lazy<int> lazyGetSum = new Lazy<int>(new Func<int>(() => X + Y));
  • @RobertHarvey 不起作用,因为您无法访问 Func<int> 内的非静态成员(在您的示例中)。
  • 什么非静态成员?
  • @RobertHarvey 请参阅 OP 中链接的问题。确实如此new Lazy<int>(() => X + Y) 其中XY 是实例成员。
  • 您必须在 Internet 上进行一些探索,但我很确定这是正确的方法。另见entityframework.net/knowledge-base/31793997

标签: c# static lazy-loading


【解决方案1】:

感谢 Robert Harvey,我找到了以下解决方案:首先,您必须在数据模型模板 MyModeName.tt 中添加一些内容,您可以在项目中的 MyModelName.edmx 下找到该模板。我添加了一个新的部分方法private partial void OnConstructorCompletion(); 并在构造函数的末尾调用它。我将文档修改如下(第 27-67 行):

<#=codeStringGenerator.EntityClassOpening(entity)#>
{
    private partial void OnConstructorCompletion();

<#
    var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
    var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
    var complexProperties = typeMapper.GetComplexProperties(entity);

    if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
    {
#>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public <#=code.Escape(entity)#>()
    {
<#
        foreach (var edmProperty in propertiesWithDefaultValues)
        {
#>
        this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
<#
        }

        foreach (var navigationProperty in collectionNavigationProperties)
        {
#>
        this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
<#
        }

        foreach (var complexProperty in complexProperties)
        {
#>
        this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
<#
        }
#>

        OnConstructorCompletion();
    }

接下来,我在实体类中实现了所需的方法:

public partial class MyEntity
{
    public Lazy<ICollection<MyNavigationEntity>> NavigationProperty;

    private partial void OnConstructorCompletion()
    {
        NavigationProperty= new Lazy<ICollection<MyNavigationEntity>>(() =>
        {
            DatabaseEntities db = (DatabaseEntities)EntityContextExtensions.GetDbContextFromEntity(this);

            return db.MyNavigationEntity
                .Where(ne => ne.ID == this.ID_MyNavigationEntity)
                .ToHashSet();
        });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-28
    • 2011-09-30
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 2011-05-31
    相关资源
    最近更新 更多