问:
How can I name a navigation property a different name from it's entity name in my EF POCO?
I have a POCO Entity named Employee.
And then I have a second POCO Entity named Case.

I want a navigation property that looks like instead this:

```<code>public class Case : BaseEntity
{
    public long EmployeeId { get; set; }
    public virtual Employee Employee{ get; set; }
</code>```

like this:

```<code>public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    public virtual Employee InitialContact { get; set; }
</code>```

I want to name my property InitialContact.  Not Employee.

But I get this error when EF tries to create the Database:

Unable to determine the relationship represented by navigation property 'Case.InitialContact' of type 'Employee'. Either manually configure the relationship, or ignore this property from the model.

Update 1:

I got it to work like this:

```<code>public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    [ForeignKey("Id")]
    public virtual Employee InitialContact { get; set; }
    public DateTime InitalConsultDate { get; set; }
    public Guid AppUserId { get; set; }
    public virtual AppUser LerSpecialist { get; set; }
</code>```

}

The primary key is ID in my BaseEntity.  Not EmployeeId.

But I have second part to my question.

Here is my Complete Employee POCO:

```<code>using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using Hrsa.Core.Generic.Model.Framework.Concrete;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace Hrsa.Core.Generic.Model.Lerd
{
    public class Employee : BaseEntity
    {
        [BindNever]
        public string Email { get; set; }
        [BindNever]
        public long OrganizationId { get; set; }
        [BindNever]
        public string Supervisor { get; set; }
        [BindNever]
        public string SupervisorEmail { get; set; }
        [BindNever]
        public string FirstName { get; set; }
        [BindNever]
        public string LastName { get; set; }
        public string Notes { get; set; }
        [BindNever]
        public  long BargainingUnitId { get; set; }
        [BindNever]
        public long PayPlanId { get; set; }
        [BindNever]
        public long GradeRankId { get; set; }
        [BindNever]
        public long PositionTitleId { get; set; }
        [BindNever]
        public long SeriesId { get; set; }
        public bool IsUnionEmployee { get; set; }
        public virtual Organization Organization { get; set; }
        public virtual BargainingUnit BargainingUnit { get; set; }
        public virtual PayPlan PayPlan { get; set; }
        public virtual GradeRank GradeRank { get; set; }
        public virtual PositionTitle PositionTitle { get; set; }
        public virtual  Series Series { get; set; }
        public virtual ICollection<UnionHours> UnionHours { get; set; }
        public virtual ICollection<Case> Cases { get; set; }
        [NotMapped]
        public string UnionEmployeeYesNo => (IsUnionEmployee) ? "Yes" : "No";
   }
}
</code>```

I want my Employee to have many Cases:

```<code>public virtual ICollection<Case> Cases { get; set; }
</code>```

Here is my complete Cases POCO:

```<code>public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    [ForeignKey("Id")]
    public virtual Employee InitialContact { get; set; }
    public DateTime InitalConsultDate { get; set; }
    public Guid AppUserId { get; set; }
    public virtual AppUser LerSpecialist { get; set; }

}
</code>```

So now my DB looks like this:

So I have my InitialContactId in Cases ok.

But now I need my Case to have many Employees.

So I add this in to my Case POCO:

```<code>public virtual ICollection<Employee> Employees { get; set; }
</code>```

Now it looks like this:

```<code>public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    [ForeignKey("Id")]
    public virtual Employee InitialContact { get; set; }
    public DateTime InitalConsultDate { get; set; }
    public Guid AppUserId { get; set; }
    public virtual AppUser LerSpecialist { get; set; }

    public virtual ICollection<Employee> Employees { get; set; }
</code>```

}

Now when I run it, I get this error again:

Unable to determine the relationship represented by navigation property 'Case.InitialContact' of type 'Employee'. Either manually configure the relationship, or ignore this property from the model.

Update 2:

I found this article for a Many-Many relationship in .Net Core 1:
http://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration

So now I have a bridge lookup entity:

```<code>public class EmployeeCase
{
    [ForeignKey("Id")]
    public long EmployeeId { get; set; }
    public Employee Employee { get; set; }
    [ForeignKey("Id")]
    public long CaseId { get; set; }
    public Case Case { get; set; }

}
</code>```

Employee POCO:

Changed:

```<code>public virtual ICollection<Case> Cases { get; set; }
</code>```

to:

```<code>public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    public virtual Employee InitialContact { get; set; }
</code>```0

Case POCO:

Changed:

```<code>public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    public virtual Employee InitialContact { get; set; }
</code>```1

to:

```<code>public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    public virtual Employee InitialContact { get; set; }
</code>```2

In my AppDbContext

```<code>    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        #region Many-to-Many Employees Cases
        modelBuilder.Entity<EmployeeCase>()
            .HasKey(ec => new { ec.EmployeeId, ec.CaseId });

        modelBuilder.Entity<EmployeeCase>()
            .HasOne(ec => ec.Employee)
            .WithMany(e => e.EmployeeCases)
            .HasForeignKey(ec => ec.EmployeeId);

        modelBuilder.Entity<EmployeeCase>()
            .HasOne(ec => ec.Case)
            .WithMany(c => c.EmployeeCases)
            .HasForeignKey(ec => ec.CaseId);
        #endregion

    }
</code>```

Now when I run I get this error:

An exception of type 'System.Data.SqlClient.SqlException' occurred in Microsoft.EntityFrameworkCore.Relational.dll but was not handled in user code

Additional information: Introducing FOREIGN KEY constraint 'FK_EmployeeCase_Employees_EmployeeId' on table 'EmployeeCase' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

Could not create constraint or index. See previous errors.

Update 3:

Finally got my tables the way I want with this piece of code from:
Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths - why?

```<code>protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Get rid of Cascading Circular error on ModelBuilding
        foreach (var relationShip in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
        {
            relationShip.DeleteBehavior = DeleteBehavior.Restrict;
        }

        #region Many-to-Many Employees Cases
        modelBuilder.Entity<EmployeeCase>()
            .HasKey(ec => new { ec.EmployeeId, ec.CaseId });

        modelBuilder.Entity<EmployeeCase>()
            .HasOne(ec => ec.Employee)
            .WithMany(e => e.EmployeeCases)
            .HasForeignKey(ec => ec.EmployeeId);

        modelBuilder.Entity<EmployeeCase>()
            .HasOne(ec => ec.Case)
            .WithMany(c => c.EmployeeCases)
            .HasForeignKey(ec => ec.CaseId);
        #endregion

        base.OnModelCreating(modelBuilder);
    }
</code>```

Update 4:

This did not work after all.
Remvoving the delete behavior for everything messes up my other relationships and I get errors.

How can I fix this?
This is disgusting.
So wishing I did not go Core.

答:
This is what worked finally for the Cascading Delete circular references on the many-to-many in EF Core:

```<code>        // Get rid of Cascading Delete Circular references error.
        var type = modelBuilder.Model.GetEntityTypes().Single(t => t.Name == "Hrsa.Core.Generic.Model.Lerd.EmployeeCase");
        foreach (var relationship in type.GetForeignKeys())
        {
            relationship.DeleteBehavior = DeleteBehavior.Restrict;
        }
</code>```

You have to get the Entity representing the many to many lookup only.
And from there restrict the DeleteBehavior.

Body:
I have a POCO Entity named Employee.
And then I have a second POCO Entity named Case.

I want a navigation property that looks like instead this:

public class Case : BaseEntity
{
    public long EmployeeId { get; set; }
    public virtual Employee Employee{ get; set; }

like this:

public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    public virtual Employee InitialContact { get; set; }

I want to name my property InitialContact.  Not Employee.

But I get this error when EF tries to create the Database:

Unable to determine the relationship represented by navigation property 'Case.InitialContact' of type 'Employee'. Either manually configure the relationship, or ignore this property from the model.

Update 1:

I got it to work like this:

public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    [ForeignKey("Id")]
    public virtual Employee InitialContact { get; set; }
    public DateTime InitalConsultDate { get; set; }
    public Guid AppUserId { get; set; }
    public virtual AppUser LerSpecialist { get; set; }

}

The primary key is ID in my BaseEntity.  Not EmployeeId.

But I have second part to my question.

Here is my Complete Employee POCO:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using Hrsa.Core.Generic.Model.Framework.Concrete;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace Hrsa.Core.Generic.Model.Lerd
{
    public class Employee : BaseEntity
    {
        [BindNever]
        public string Email { get; set; }
        [BindNever]
        public long OrganizationId { get; set; }
        [BindNever]
        public string Supervisor { get; set; }
        [BindNever]
        public string SupervisorEmail { get; set; }
        [BindNever]
        public string FirstName { get; set; }
        [BindNever]
        public string LastName { get; set; }
        public string Notes { get; set; }
        [BindNever]
        public  long BargainingUnitId { get; set; }
        [BindNever]
        public long PayPlanId { get; set; }
        [BindNever]
        public long GradeRankId { get; set; }
        [BindNever]
        public long PositionTitleId { get; set; }
        [BindNever]
        public long SeriesId { get; set; }
        public bool IsUnionEmployee { get; set; }
        public virtual Organization Organization { get; set; }
        public virtual BargainingUnit BargainingUnit { get; set; }
        public virtual PayPlan PayPlan { get; set; }
        public virtual GradeRank GradeRank { get; set; }
        public virtual PositionTitle PositionTitle { get; set; }
        public virtual  Series Series { get; set; }
        public virtual ICollection<UnionHours> UnionHours { get; set; }
        public virtual ICollection<Case> Cases { get; set; }
        [NotMapped]
        public string UnionEmployeeYesNo => (IsUnionEmployee) ? "Yes" : "No";
   }
}

I want my Employee to have many Cases:

public virtual ICollection<Case> Cases { get; set; }

Here is my complete Cases POCO:

public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    [ForeignKey("Id")]
    public virtual Employee InitialContact { get; set; }
    public DateTime InitalConsultDate { get; set; }
    public Guid AppUserId { get; set; }
    public virtual AppUser LerSpecialist { get; set; }

}

So now my DB looks like this:

So I have my InitialContactId in Cases ok.

But now I need my Case to have many Employees.

So I add this in to my Case POCO:

public virtual ICollection<Employee> Employees { get; set; }

Now it looks like this:

public class Case : BaseEntity
{
    public long InitialContactId { get; set; }
    [ForeignKey("Id")]
    public virtual Employee InitialContact { get; set; }
    public DateTime InitalConsultDate { get; set; }
    public Guid AppUserId { get; set; }
    public virtual AppUser LerSpecialist { get; set; }

    public virtual ICollection<Employee> Employees { get; set; }

}

Now when I run it, I get this error again:

Unable to determine the relationship represented by navigation property 'Case.InitialContact' of type 'Employee'. Either manually configure the relationship, or ignore this property from the model.

Update 2:

I found this article for a Many-Many relationship in .Net Core 1:
http://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration

So now I have a bridge lookup entity:

public class EmployeeCase
{
    [ForeignKey("Id")]
    public long EmployeeId { get; set; }
    public Employee Employee { get; set; }
    [ForeignKey("Id")]
    public long CaseId { get; set; }
    public Case Case { get; set; }

}

Employee POCO:

Changed:

public virtual ICollection<Case> Cases { get; set; }

to:

// Mapping - Collection of Cases
public virtual ICollection<EmployeeCase> EmployeeCases { get; set; }

Case POCO:

Changed:

public virtual ICollection<Employee> Employees { get; set; }

to:

 // Mapping - Collection of Employees
public virtual ICollection<EmployeeCase> EmployeeCases { get; set; }

In my AppDbContext

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        #region Many-to-Many Employees Cases
        modelBuilder.Entity<EmployeeCase>()
            .HasKey(ec => new { ec.EmployeeId, ec.CaseId });

        modelBuilder.Entity<EmployeeCase>()
            .HasOne(ec => ec.Employee)
            .WithMany(e => e.EmployeeCases)
            .HasForeignKey(ec => ec.EmployeeId);

        modelBuilder.Entity<EmployeeCase>()
            .HasOne(ec => ec.Case)
            .WithMany(c => c.EmployeeCases)
            .HasForeignKey(ec => ec.CaseId);
        #endregion

    }

Now when I run I get this error:

An exception of type 'System.Data.SqlClient.SqlException' occurred in Microsoft.EntityFrameworkCore.Relational.dll but was not handled in user code

Additional information: Introducing FOREIGN KEY constraint 'FK_EmployeeCase_Employees_EmployeeId' on table 'EmployeeCase' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

Could not create constraint or index. See previous errors.

Update 3:

Finally got my tables the way I want with this piece of code from:
Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths - why?

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Get rid of Cascading Circular error on ModelBuilding
        foreach (var relationShip in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
        {
            relationShip.DeleteBehavior = DeleteBehavior.Restrict;
        }

        #region Many-to-Many Employees Cases
        modelBuilder.Entity<EmployeeCase>()
            .HasKey(ec => new { ec.EmployeeId, ec.CaseId });

        modelBuilder.Entity<EmployeeCase>()
            .HasOne(ec => ec.Employee)
            .WithMany(e => e.EmployeeCases)
            .HasForeignKey(ec => ec.EmployeeId);

        modelBuilder.Entity<EmployeeCase>()
            .HasOne(ec => ec.Case)
            .WithMany(c => c.EmployeeCases)
            .HasForeignKey(ec => ec.CaseId);
        #endregion

        base.OnModelCreating(modelBuilder);
    }

Update 4:

This did not work after all.
Remvoving the delete behavior for everything messes up my other relationships and I get errors.

How can I fix this?
This is disgusting.
So wishing I did not go Core.

Body:
This is what worked finally for the Cascading Delete circular references on the many-to-many in EF Core:

        // Get rid of Cascading Delete Circular references error.
        var type = modelBuilder.Model.GetEntityTypes().Single(t => t.Name == "Hrsa.Core.Generic.Model.Lerd.EmployeeCase");
        foreach (var relationship in type.GetForeignKeys())
        {
            relationship.DeleteBehavior = DeleteBehavior.Restrict;
        }

You have to get the Entity representing the many to many lookup only.
And from there restrict the DeleteBehavior.


来源: stackexchange

问:
How do I mock a jQuery plugin?
I am writing a plugin which uses an existing plugin which I would like to mock out.

The plugin I'm writing looks sort of like this:

```<code>(function($){
  $.widget("myPlugin",{
    _create: function(){
      var otherControl = $("<div></div>");
      otherControl.pluginWhichShouldBeMocked({foo: "bar"});
      this.element.append(otherControl);
    }
  });
})(jQuery);
</code>```

And I have a Jasmine test which sort of looks like this:

```<code>describe("When creating", function(){
  var element;
  var passedOptions;
  beforeEach(function(){
    jQuery.pluginWhichShouldBeMocked = function(options){
      passedOptions = options;
    }
    element = $("<div></div>");
    element.myPlugin();
  });

  it("should create the other plugin and pass 'bar' to it as the foo parameter", function(){
    expect(passedOptions.foo).toEqual("bar");
  });
});
</code>```

This line is where I have tried to mock the plugin:

```<code>jQuery.pluginWhichShouldBeMocked = function(options){
  passedOptions = options;
}
</code>```

The actual plugin instance is still called though.

答:
I recently went through this with Bootstrap modal and fixed with:</p>

```<code>beforeEach(()=>{
    jQuery.fn.modal = () => {}
})

describe(()=>{
   \\ ... do your thing
})

afterEach(()=>{
    delete jQuery.fn.modal
})
</code>```

ContentLicense: CC BY-SA 3.0

Title: How do I mock a jQuery plugin?

Body:
I am writing a plugin which uses an existing plugin which I would like to mock out.

The plugin I'm writing looks sort of like this:

(function($){
  $.widget("myPlugin",{
    _create: function(){
      var otherControl = $("

");
      otherControl.pluginWhichShouldBeMocked({foo: "bar"});
      this.element.append(otherControl);
    }
  });
})(jQuery);

And I have a Jasmine test which sort of looks like this:

describe("When creating", function(){
  var element;
  var passedOptions;
  beforeEach(function(){
    jQuery.pluginWhichShouldBeMocked = function(options){
      passedOptions = options;
    }
    element = $("

");
    element.myPlugin();
  });

  it("should create the other plugin and pass 'bar' to it as the foo parameter", function(){
    expect(passedOptions.foo).toEqual("bar");
  });
});

This line is where I have tried to mock the plugin:

jQuery.pluginWhichShouldBeMocked = function(options){
  passedOptions = options;
}

The actual plugin instance is still called though.

Body:
I recently went through this with Bootstrap modal and fixed with:

beforeEach(()=>{
    jQuery.fn.modal = () => {}
})

describe(()=>{
   \\ ... do your thing
})

afterEach(()=>{
    delete jQuery.fn.modal
})


问:
Horizontal LinearLayout inside Vertical LinearLayout
I want to display an horizontal linearlayout which content 3 imageview inside a vertical linearLayout

But i have a problem as you can see

Only the first Imageview is displayed , and he is in the center .

I changed the gravity for the other Imageview (left and right) but nothing changed .

The code :

```<code><?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_form"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        tools:context="info.androidhive.navigationdrawer.activity.FormActivity"
        android:weightSum="1"
        android:theme="@style/ThemeOverlay.AppCompat.Dark">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Ajouter Votre Annonce"
            android:gravity="center"
            android:textColor="#000000"
            android:textSize="22sp"
            />

        <Spinner
            android:id="@+id/spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="34dp"
            android:layout_below="@+id/textView"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:entries="@array/cat_arrays"
            android:prompt="@string/cat_prompt"
            />

        <RadioButton
            android:id="@+id/radioButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="23dp"
            android:text="Offre"
            android:layout_below="@+id/spinner"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:textColor="#000000"
            />

        <RadioButton
            android:id="@+id/radioButton2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/radioButton"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:text="Demande"
            android:textColor="#000000"
            />

        <Spinner
            android:id="@+id/spinner4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/spinner3"
            android:layout_marginTop="17dp"
            android:entries="@array/vil_arrays"
            android:prompt="@string/vil_prompt"
            android:textColor="#808080"
            />

        <EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Titre de l'Annonce"
            android:layout_below="@+id/spinner4"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"
            android:textColor="#000000"
            />

        <EditText
            android:id="@+id/editText8"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Prix en UM"
            android:layout_below="@+id/spinner4"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"
            android:textColor="#000000"
            />

        <EditText
            android:id="@+id/editText4"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/editText"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Description"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentBottom="true"
            android:textColorHint="#808080"
            android:paddingBottom="75dp"
            android:textColor="#000000"/>

        <TextView
            android:id="@+id/textView4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="27dp"
            android:text="Vos Photos"
            android:gravity="center"
            android:textColor="#000000"
            android:textSize="22sp"

            />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/img1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/imgadd"
                android:gravity="left"
                />

            <ImageView
                android:id="@+id/img2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/imgadd"
                android:gravity="center"/>

            <ImageView
                android:id="@+id/img3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/imgadd"
                android:gravity="right"/>

        </LinearLayout>

        <TextView
            android:id="@+id/textView5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/button3"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="23dp"
            android:text="Vos Informations"
            android:gravity="center"
            android:textColor="#000000"
            android:textSize="22sp"
            />

        <RadioButton
            android:id="@+id/radioButton3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button3"
            android:layout_alignStart="@+id/button3"
            android:layout_below="@+id/textView5"
            android:text="Professionel"
            android:textColor="#000000"
            />

        <RadioButton
            android:id="@+id/radioButton4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/radioButton3"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:text="Particulier"
            android:textColor="#000000"
            />

        <EditText
            android:id="@+id/editText5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button3"
            android:layout_alignStart="@+id/button3"
            android:layout_below="@+id/radioButton3"
            android:layout_marginTop="26dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Nom et Prenom"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"
            />

        <EditText
            android:id="@+id/editText6"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/editText5"
            android:layout_alignParentBottom="true"
            android:layout_alignStart="@+id/editText5"
            android:layout_marginBottom="10dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Telephone"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"
            />
        <EditText
            android:id="@+id/editText7"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/editText6"
            android:layout_alignParentBottom="true"
            android:layout_alignStart="@+id/editText6"
            android:layout_marginBottom="10dp"
            android:ems="10"
            android:inputType="textPassword"
            android:hint="Mot de passe"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"/>

        <Button
            android:id="@+id/button4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="36dp"
            android:text="Déposez votre Annonce"
            android:background="#a4c639"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:textColorHint="#808080"/>

    </LinearLayout>
</ScrollView>
</code>```

答:
```<code><LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

    <ImageView
       android:id="@+id/img1"
       android:layout_width="0dp"
       android:layout_weight = "1"
       android:layout_height="wrap_content"
       android:src="@drawable/imgadd"/>

   <ImageView
       android:id="@+id/img2"
       android:layout_width="0dp"
       android:layout_weight = "1"
       android:layout_height="wrap_content"
       android:src="@drawable/imgadd"/>

   <ImageView
       android:id="@+id/img3"
       android:layout_width="0dp"
       android:layout_weight = "1"
       android:layout_height="wrap_content"
       android:src="@drawable/imgadd"/>

</LinearLayout>
</code>```

Body:
I want to display an horizontal linearlayout which content 3 imageview inside a vertical linearLayout

But i have a problem as you can see

Only the first Imageview is displayed , and he is in the center .

I changed the gravity for the other Imageview (left and right) but nothing changed .

The code :

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_form"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        tools:context="info.androidhive.navigationdrawer.activity.FormActivity"
        android:weightSum="1"
        android:theme="@style/ThemeOverlay.AppCompat.Dark">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Ajouter Votre Annonce"
            android:gravity="center"
            android:textColor="#000000"
            android:textSize="22sp"
            />

        <Spinner
            android:id="@+id/spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="34dp"
            android:layout_below="@+id/textView"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:entries="@array/cat_arrays"
            android:prompt="@string/cat_prompt"
            />

        <RadioButton
            android:id="@+id/radioButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="23dp"
            android:text="Offre"
            android:layout_below="@+id/spinner"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:textColor="#000000"
            />

        <RadioButton
            android:id="@+id/radioButton2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/radioButton"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:text="Demande"
            android:textColor="#000000"
            />

        <Spinner
            android:id="@+id/spinner4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/spinner3"
            android:layout_marginTop="17dp"
            android:entries="@array/vil_arrays"
            android:prompt="@string/vil_prompt"
            android:textColor="#808080"
            />

        <EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Titre de l'Annonce"
            android:layout_below="@+id/spinner4"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"
            android:textColor="#000000"
            />

        <EditText
            android:id="@+id/editText8"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Prix en UM"
            android:layout_below="@+id/spinner4"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"
            android:textColor="#000000"
            />

        <EditText
            android:id="@+id/editText4"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/editText"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Description"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentBottom="true"
            android:textColorHint="#808080"
            android:paddingBottom="75dp"
            android:textColor="#000000"/>

        <TextView
            android:id="@+id/textView4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="27dp"
            android:text="Vos Photos"
            android:gravity="center"
            android:textColor="#000000"
            android:textSize="22sp"

            />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/img1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/imgadd"
                android:gravity="left"
                />

            <ImageView
                android:id="@+id/img2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/imgadd"
                android:gravity="center"/>

            <ImageView
                android:id="@+id/img3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/imgadd"
                android:gravity="right"/>

        </LinearLayout>

        <TextView
            android:id="@+id/textView5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/button3"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="23dp"
            android:text="Vos Informations"
            android:gravity="center"
            android:textColor="#000000"
            android:textSize="22sp"
            />

        <RadioButton
            android:id="@+id/radioButton3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button3"
            android:layout_alignStart="@+id/button3"
            android:layout_below="@+id/textView5"
            android:text="Professionel"
            android:textColor="#000000"
            />

        <RadioButton
            android:id="@+id/radioButton4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/radioButton3"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:text="Particulier"
            android:textColor="#000000"
            />

        <EditText
            android:id="@+id/editText5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button3"
            android:layout_alignStart="@+id/button3"
            android:layout_below="@+id/radioButton3"
            android:layout_marginTop="26dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Nom et Prenom"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"
            />

        <EditText
            android:id="@+id/editText6"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/editText5"
            android:layout_alignParentBottom="true"
            android:layout_alignStart="@+id/editText5"
            android:layout_marginBottom="10dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:hint="Telephone"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"
            />
        <EditText
            android:id="@+id/editText7"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/editText6"
            android:layout_alignParentBottom="true"
            android:layout_alignStart="@+id/editText6"
            android:layout_marginBottom="10dp"
            android:ems="10"
            android:inputType="textPassword"
            android:hint="Mot de passe"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textColorHint="#808080"/>

        <Button
            android:id="@+id/button4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="36dp"
            android:text="Déposez votre Annonce"
            android:background="#a4c639"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:textColorHint="#808080"/>

    </LinearLayout>
</ScrollView>


问:
If the null-coalescing operator is supposed to protect against null values, why would Visual Studio or ReSharper suggest a possible null solution?
So here's a generic function that I had

```<code>int SomeArray(IEnumerable<int> array, int size)
{
    int product = 1
    for (var i = 0; i < size; i++)
    {
        product *= array[i];
    }
    return product
}
</code>```

Visual Studio or ReSharper, I'm not sure which, suggested that I change array[i] to enumerate as array by changing the function to be

```<code>var enumerable = array as int[] ?? array.ToArray();
for (var i = 0; i < size; i++)
{
    product *= enumerable[i];
}
</code>```

The problem I see is that the passed in array could be null and Visual Studio does warn against a possible System.NullReferenceException being thrown.

The real question is that the idea of the null-coalescing operator is that if the operand on the left is null then the operand on the right will be used.

If I do var enumerable = array as int[] ?? array.ToArray() ?? new int[size]; The new int[size] is marked as being not needed because the according to Visual Studio the stuff on the left could never be null. When I can clearly force the passed in array to be null.

So what am I not getting here?

答:
If array was null then that line of code would call array.ToArray on that null value, and it'll throw an argument null exception.

ToArray will never return a null value (even if a null value is provided) which is why your array constructor can never be called.

Body:
So here's a generic function that I had

int SomeArray(IEnumerable<int> array, int size)
{
    int product = 1
    for (var i = 0; i < size; i++)
    {
        product *= array[i];
    }
    return product
}

Visual Studio or ReSharper, I'm not sure which, suggested that I change array[i] to enumerate as array by changing the function to be

var enumerable = array as int[] ?? array.ToArray();
for (var i = 0; i < size; i++)
{
    product *= enumerable[i];
}

The problem I see is that the passed in array could be null and Visual Studio does warn against a possible System.NullReferenceException being thrown.

The real question is that the idea of the null-coalescing operator is that if the operand on the left is null then the operand on the right will be used.

If I do var enumerable = array as int[] ?? array.ToArray() ?? new int[size]; The new int[size] is marked as being not needed because the according to Visual Studio the stuff on the left could never be null. When I can clearly force the passed in array to be null.

So what am I not getting here?


问:
Error: Cannot reattach ActivatedRouteSnapshot created from a different route
I am trying to implement the RouteReuseStrategy class. It works fine when I navigate to top level paths.

As soon as a path has child paths and I navigate to the child path, then navigate back to a top level path I receive the following error:

Error: Uncaught (in promise): Error: Cannot reattach ActivatedRouteSnapshot created from a different route

I have created a plunker to demonstrate the error. I see the plunker does not work in IE 11, please view it in the latest version of Chrome

Steps to reproduce the error:

Step1:

Step2

Step3

Step4

You can view the error in the console:

I have tried the implementation found on this article

```<code>export class CustomReuseStrategy implements RouteReuseStrategy {

    handlers: {[key: string]: DetachedRouteHandle} = {};

    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldDetach', route);
        return true;
    }

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        console.debug('CustomReuseStrategy:store', route, handle);
        this.handlers[route.routeConfig.path] = handle;
    }

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldAttach', route);
        return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
    }

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        console.debug('CustomReuseStrategy:retrieve', route);
        if (!route.routeConfig) return null;
        return this.handlers[route.routeConfig.path];
    }

    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldReuseRoute', future, curr);
        return future.routeConfig === curr.routeConfig;
    }

}
</code>```

And the implementation of this stackoverflow answer

```<code>/**
 * reuse-strategy.ts
 * by corbfon 1/6/17
 */

import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';

/** Interface for object which can store both:
 * An ActivatedRouteSnapshot, which is useful for determining whether or not you should attach a route (see this.shouldAttach)
 * A DetachedRouteHandle, which is offered up by this.retrieve, in the case that you do want to attach the stored route
 */
interface RouteStorageObject {
    snapshot: ActivatedRouteSnapshot;
    handle: DetachedRouteHandle;
}

export class CustomReuseStrategy implements RouteReuseStrategy {

    /**
     * Object which will store RouteStorageObjects indexed by keys
     * The keys will all be a path (as in route.routeConfig.path)
     * This allows us to see if we've got a route stored for the requested path
     */
    storedRoutes: { [key: string]: RouteStorageObject } = {};

    /**
     * Decides when the route should be stored
     * If the route should be stored, I believe the boolean is indicating to a controller whether or not to fire this.store
     * _When_ it is called though does not particularly matter, just know that this determines whether or not we store the route
     * An idea of what to do here: check the route.routeConfig.path to see if it is a path you would like to store
     * @param route This is, at least as I understand it, the route that the user is currently on, and we would like to know if we want to store it
     * @returns boolean indicating that we want to (true) or do not want to (false) store that route
     */
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        let detach: boolean = true;
        console.log("detaching", route, "return: ", detach);
        return detach;
    }

    /**
     * Constructs object of type `RouteStorageObject` to store, and then stores it for later attachment
     * @param route This is stored for later comparison to requested routes, see `this.shouldAttach`
     * @param handle Later to be retrieved by this.retrieve, and offered up to whatever controller is using this class
     */
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        let storedRoute: RouteStorageObject = {
            snapshot: route,
            handle: handle
        };

        console.log("store:", storedRoute, "into: ", this.storedRoutes);
        // routes are stored by path - the key is the path name, and the handle is stored under it so that you can only ever have one object stored for a single path
        this.storedRoutes[route.routeConfig.path] = storedRoute;
    }

    /**
     * Determines whether or not there is a stored route and, if there is, whether or not it should be rendered in place of requested route
     * @param route The route the user requested
     * @returns boolean indicating whether or not to render the stored route
     */
    shouldAttach(route: ActivatedRouteSnapshot): boolean {

        // this will be true if the route has been stored before
        let canAttach: boolean = !!route.routeConfig && !!this.storedRoutes[route.routeConfig.path];

        // this decides whether the route already stored should be rendered in place of the requested route, and is the return value
        // at this point we already know that the paths match because the storedResults key is the route.routeConfig.path
        // so, if the route.params and route.queryParams also match, then we should reuse the component
        if (canAttach) {
            let willAttach: boolean = true;
            console.log("param comparison:");
            console.log(this.compareObjects(route.params, this.storedRoutes[route.routeConfig.path].snapshot.params));
            console.log("query param comparison");
            console.log(this.compareObjects(route.queryParams, this.storedRoutes[route.routeConfig.path].snapshot.queryParams));

            let paramsMatch: boolean = this.compareObjects(route.params, this.storedRoutes[route.routeConfig.path].snapshot.params);
            let queryParamsMatch: boolean = this.compareObjects(route.queryParams, this.storedRoutes[route.routeConfig.path].snapshot.queryParams);

            console.log("deciding to attach...", route, "does it match?", this.storedRoutes[route.routeConfig.path].snapshot, "return: ", paramsMatch && queryParamsMatch);
            return paramsMatch && queryParamsMatch;
        } else {
            return false;
        }
    }

    /**
     * Finds the locally stored instance of the requested route, if it exists, and returns it
     * @param route New route the user has requested
     * @returns DetachedRouteHandle object which can be used to render the component
     */
    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {

        // return null if the path does not have a routerConfig OR if there is no stored route for that routerConfig
        if (!route.routeConfig || !this.storedRoutes[route.routeConfig.path]) return null;
        console.log("retrieving", "return: ", this.storedRoutes[route.routeConfig.path]);

        /** returns handle when the route.routeConfig.path is already stored */
        return this.storedRoutes[route.routeConfig.path].handle;
    }

    /**
     * Determines whether or not the current route should be reused
     * @param future The route the user is going to, as triggered by the router
     * @param curr The route the user is currently on
     * @returns boolean basically indicating true if the user intends to leave the current route
     */
    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        console.log("deciding to reuse", "future", future.routeConfig, "current", curr.routeConfig, "return: ", future.routeConfig === curr.routeConfig);
        return future.routeConfig === curr.routeConfig;
    }

    /**
     * This nasty bugger finds out whether the objects are _traditionally_ equal to each other, like you might assume someone else would have put this function in vanilla JS already
     * One thing to note is that it uses coercive comparison (==) on properties which both objects have, not strict comparison (===)
     * @param base The base object which you would like to compare another object to
     * @param compare The object to compare to base
     * @returns boolean indicating whether or not the objects have all the same properties and those properties are ==
     */
    private compareObjects(base: any, compare: any): boolean {

        // loop through all properties in base object
        for (let baseProperty in base) {

            // determine if comparrison object has that property, if not: return false
            if (compare.hasOwnProperty(baseProperty)) {
                switch (typeof base[baseProperty]) {
                    // if one is object and other is not: return false
                    // if they are both objects, recursively call this comparison function
                    case 'object':
                        if (typeof compare[baseProperty] !== 'object' || !this.compareObjects(base[baseProperty], compare[baseProperty])) { return false; } break;
                    // if one is function and other is not: return false
                    // if both are functions, compare function.toString() results
                    case 'function':
                        if (typeof compare[baseProperty] !== 'function' || base[baseProperty].toString() !== compare[baseProperty].toString()) { return false; } break;
                    // otherwise, see if they are equal using coercive comparison
                    default:
                        if (base[baseProperty] != compare[baseProperty]) { return false; }
                }
            } else {
                return false;
            }
        }

        // returns true only after false HAS NOT BEEN returned through all loops
        return true;
    }
}
</code>```

Is RouteReuseStrategy ready for child paths? Or is there another way to get RouteReuseStrategy working with paths that contain child paths

答:
I added a workaround to never retrieve detached routes when on a route with loadChildren by modifying my retrieve function in the custom RouteReuseStrategy.

```<code>    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
       if (!route.routeConfig) return null;
       if(route.routeConfig.loadChildren) return null;
       return this.handlers[route.routeConfig.path];
    }
</code>```

I'm not sure it is a perfect solution for all scenarios but in my case it works.

Body:
I am trying to implement the RouteReuseStrategy class. It works fine when I navigate to top level paths.

As soon as a path has child paths and I navigate to the child path, then navigate back to a top level path I receive the following error:

Error: Uncaught (in promise): Error: Cannot reattach ActivatedRouteSnapshot created from a different route

I have created a plunker to demonstrate the error. I see the plunker does not work in IE 11, please view it in the latest version of Chrome

Steps to reproduce the error:

Step1:

Step2

Step3

Step4

You can view the error in the console:

I have tried the implementation found on this article

export class CustomReuseStrategy implements RouteReuseStrategy {

    handlers: {[key: string]: DetachedRouteHandle} = {};

    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldDetach', route);
        return true;
    }

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        console.debug('CustomReuseStrategy:store', route, handle);
        this.handlers[route.routeConfig.path] = handle;
    }

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldAttach', route);
        return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
    }

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        console.debug('CustomReuseStrategy:retrieve', route);
        if (!route.routeConfig) return null;
        return this.handlers[route.routeConfig.path];
    }

    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldReuseRoute', future, curr);
        return future.routeConfig === curr.routeConfig;
    }

}

And the implementation of this stackoverflow answer

/**
 * reuse-strategy.ts
 * by corbfon 1/6/17
 */

import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';

/** Interface for object which can store both:
 * An ActivatedRouteSnapshot, which is useful for determining whether or not you should attach a route (see this.shouldAttach)
 * A DetachedRouteHandle, which is offered up by this.retrieve, in the case that you do want to attach the stored route
 */
interface RouteStorageObject {
    snapshot: ActivatedRouteSnapshot;
    handle: DetachedRouteHandle;
}

export class CustomReuseStrategy implements RouteReuseStrategy {

    /**
     * Object which will store RouteStorageObjects indexed by keys
     * The keys will all be a path (as in route.routeConfig.path)
     * This allows us to see if we've got a route stored for the requested path
     */
    storedRoutes: { [key: string]: RouteStorageObject } = {};

    /**
     * Decides when the route should be stored
     * If the route should be stored, I believe the boolean is indicating to a controller whether or not to fire this.store
     * _When_ it is called though does not particularly matter, just know that this determines whether or not we store the route
     * An idea of what to do here: check the route.routeConfig.path to see if it is a path you would like to store
     * @param route This is, at least as I understand it, the route that the user is currently on, and we would like to know if we want to store it
     * @returns boolean indicating that we want to (true) or do not want to (false) store that route
     */
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        let detach: boolean = true;
        console.log("detaching", route, "return: ", detach);
        return detach;
    }

    /**
     * Constructs object of type `RouteStorageObject` to store, and then stores it for later attachment
     * @param route This is stored for later comparison to requested routes, see `this.shouldAttach`
     * @param handle Later to be retrieved by this.retrieve, and offered up to whatever controller is using this class
     */
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        let storedRoute: RouteStorageObject = {
            snapshot: route,
            handle: handle
        };

        console.log("store:", storedRoute, "into: ", this.storedRoutes);
        // routes are stored by path - the key is the path name, and the handle is stored under it so that you can only ever have one object stored for a single path
        this.storedRoutes[route.routeConfig.path] = storedRoute;
    }

    /**
     * Determines whether or not there is a stored route and, if there is, whether or not it should be rendered in place of requested route
     * @param route The route the user requested
     * @returns boolean indicating whether or not to render the stored route
     */
    shouldAttach(route: ActivatedRouteSnapshot): boolean {

        // this will be true if the route has been stored before
        let canAttach: boolean = !!route.routeConfig && !!this.storedRoutes[route.routeConfig.path];

        // this decides whether the route already stored should be rendered in place of the requested route, and is the return value
        // at this point we already know that the paths match because the storedResults key is the route.routeConfig.path
        // so, if the route.params and route.queryParams also match, then we should reuse the component
        if (canAttach) {
            let willAttach: boolean = true;
            console.log("param comparison:");
            console.log(this.compareObjects(route.params, this.storedRoutes[route.routeConfig.path].snapshot.params));
            console.log("query param comparison");
            console.log(this.compareObjects(route.queryParams, this.storedRoutes[route.routeConfig.path].snapshot.queryParams));

            let paramsMatch: boolean = this.compareObjects(route.params, this.storedRoutes[route.routeConfig.path].snapshot.params);
            let queryParamsMatch: boolean = this.compareObjects(route.queryParams, this.storedRoutes[route.routeConfig.path].snapshot.queryParams);

            console.log("deciding to attach...", route, "does it match?", this.storedRoutes[route.routeConfig.path].snapshot, "return: ", paramsMatch && queryParamsMatch);
            return paramsMatch && queryParamsMatch;
        } else {
            return false;
        }
    }

    /**
     * Finds the locally stored instance of the requested route, if it exists, and returns it
     * @param route New route the user has requested
     * @returns DetachedRouteHandle object which can be used to render the component
     */
    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {

        // return null if the path does not have a routerConfig OR if there is no stored route for that routerConfig
        if (!route.routeConfig || !this.storedRoutes[route.routeConfig.path]) return null;
        console.log("retrieving", "return: ", this.storedRoutes[route.routeConfig.path]);

        /** returns handle when the route.routeConfig.path is already stored */
        return this.storedRoutes[route.routeConfig.path].handle;
    }

    /**
     * Determines whether or not the current route should be reused
     * @param future The route the user is going to, as triggered by the router
     * @param curr The route the user is currently on
     * @returns boolean basically indicating true if the user intends to leave the current route
     */
    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        console.log("deciding to reuse", "future", future.routeConfig, "current", curr.routeConfig, "return: ", future.routeConfig === curr.routeConfig);
        return future.routeConfig === curr.routeConfig;
    }

    /**
     * This nasty bugger finds out whether the objects are _traditionally_ equal to each other, like you might assume someone else would have put this function in vanilla JS already
     * One thing to note is that it uses coercive comparison (==) on properties which both objects have, not strict comparison (===)
     * @param base The base object which you would like to compare another object to
     * @param compare The object to compare to base
     * @returns boolean indicating whether or not the objects have all the same properties and those properties are ==
     */
    private compareObjects(base: any, compare: any): boolean {

        // loop through all properties in base object
        for (let baseProperty in base) {

            // determine if comparrison object has that property, if not: return false
            if (compare.hasOwnProperty(baseProperty)) {
                switch (typeof base[baseProperty]) {
                    // if one is object and other is not: return false
                    // if they are both objects, recursively call this comparison function
                    case 'object':
                        if (typeof compare[baseProperty] !== 'object' || !this.compareObjects(base[baseProperty], compare[baseProperty])) { return false; } break;
                    // if one is function and other is not: return false
                    // if both are functions, compare function.toString() results
                    case 'function':
                        if (typeof compare[baseProperty] !== 'function' || base[baseProperty].toString() !== compare[baseProperty].toString()) { return false; } break;
                    // otherwise, see if they are equal using coercive comparison
                    default:
                        if (base[baseProperty] != compare[baseProperty]) { return false; }
                }
            } else {
                return false;
            }
        }

        // returns true only after false HAS NOT BEEN returned through all loops
        return true;
    }
}

Is RouteReuseStrategy ready for child paths? Or is there another way to get RouteReuseStrategy working with paths that contain child paths

Body:
I added a workaround to never retrieve detached routes when on a route with loadChildren by modifying my retrieve function in the custom RouteReuseStrategy.

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
       if (!route.routeConfig) return null;
       if(route.routeConfig.loadChildren) return null;
       return this.handlers[route.routeConfig.path];
    }

I'm not sure it is a perfect solution for all scenarios but in my case it works.


问:
How to get part of a key in a ruby hash
How do I get 1 from a hash that looks like this?

```<code>{{1=>2} => 3}
</code>```

ContentLicense: CC BY-SA 2.5

Title: How to get part of a key in a ruby hash

Body:
How do I get 1 from a hash that looks like this?

{{1=>2} => 3}


问:
Javascript Image Slider - Need to add buttons
Please see my code below. This code works fine but i want to add pause/resume,forward,backward buttons. So if someone click on pause, it will stop auto rotation. I can't use Jquery. I worked on this code but i am not able to add buttons to this code.

(function() {

    function Slideshow( element ) {
        this.el = document.querySelector( element );
        this.init();
    }

    Slideshow.prototype = {
        init: function() {
            this.wrapper = this.el.querySelector( ".slider-wrapper" );
            this.slides = this.el.querySelectorAll( ".slide" );
            this.previous = this.el.querySelector( ".slider-previous" );
            this.next = this.el.querySelector( ".slider-next" );
            this.index = 0;
            this.total = this.slides.length;
            this.timer = null;

            this.action();
            this.stopStart();
        },
        _slideTo: function( slide ) {
            var currentSlide = this.slides[slide];
            currentSlide.style.opacity = 1;

            for( var i = 0; i < this.slides.length; i++ ) {
                var slide = this.slides[i];
                if( slide !== currentSlide ) {
                    slide.style.opacity = 0;
                }
            }
        },
        action: function() {
            var self = this;
            self.timer = setInterval(function() {
                self.index++;
                if( self.index == self.slides.length ) {
                    self.index = 0;
                }
                self._slideTo( self.index );

            }, 3000);
        },
        stopStart: function() {
            var self = this;
            self.el.addEventListener( "mouseover", function() {
                clearInterval( self.timer );
                self.timer = null;

            }, false);
            self.el.addEventListener( "mouseout", function() {
                self.action();

            }, false);
        }

    };

    document.addEventListener( "DOMContentLoaded", function() {

        var slider = new Slideshow( "#main-slider" );

    });

})();```
<pre class="snippet-code-css lang-css prettyprint-override"><code>html,body {
    margin: 0;
    padding: 0;
}
.slider {
    width: 1024px;
    margin: 2em auto;

}

.slider-wrapper {
    width: 100%;
    height: 400px;
    position: relative;
}

.slide {
    float: left;
    position: absolute;
    width: 100%;
    height: 100%;
    opacity: 0;
    transition: opacity 3s linear;
}

.slider-wrapper > .slide:first-child {
    opacity: 1;
}</code>```

  ```

答:
This can be done this way.

(function() {

    function Slideshow( element ) {
        this.el = document.querySelector( element );
        this.init();
    }

    Slideshow.prototype = {
        init: function() {
            this.wrapper = this.el.querySelector( ".slider-wrapper" );
            this.slides = this.el.querySelectorAll( ".slide" );
            this.index = 0;
            this.total = this.slides.length;
            this.timer = null;
   this.nextButton = document.querySelector('#next');
   this.previousButton = document.querySelector('#previous');
   this.toggleButton = document.querySelector('#toggle');
            this.action();
            this.stopStart();
   this.toggleButton.addEventListener('click', function(e){
    e.preventDefault();
    this.stop();
   }.bind(this));
   this.nextButton.addEventListener('click', function(e){
    e.preventDefault();
    this.next();
   }.bind(this));
   this.previousButton.addEventListener('click', function(e){
    e.preventDefault();
    this.previous();
   }.bind(this))
        },
        _slideTo: function( slide ) {
            var currentSlide = this.slides[slide];
            currentSlide.style.opacity = 1;

            for( var i = 0; i < this.slides.length; i++ ) {
                 slide = this.slides[i];
                if( slide !== currentSlide ) {
                    slide.style.opacity = 0;
                }
            }
        },
        action: function() {
            var self = this;
            this.timer = setInterval(function() {
                self.index++;
                if( self.index == self.slides.length ) {
                    self.index = 0;
                }
                self._slideTo( self.index );

            }, 5000);
        },
        stopStart: function() {
            var self = this;
            self.el.addEventListener( "mouseover", function(){
     clearInterval( self.timer );
     self.timer = null;
   }, false);
            self.el.addEventListener( "mouseout", function() {
                self.action();

            }, false);
        },
  stop: function(){
   if(this.timer){
    clearInterval( this.timer );
    this.timer = null;
    this.toggleButton.innerText = 'Play';
   }else{
    this.action();
    this.toggleButton.innerText = 'Pause';
   }

  },
  next: function(){
   this.index++;
   if( this.index === this.slides.length ) {
    this.index = 0;
   }
   this._slideTo(this.index);

  },
  previous: function(){
   this.index--;
   if( this.index <= 0 ) {
    this.index = this.slides.length - 1;
   }
   this._slideTo(this.index);
  }

    };
    document.addEventListener( "DOMContentLoaded", function() {

        var slider = new Slideshow( "#main-slider" );

    });

})();```
<pre class="snippet-code-css lang-css prettyprint-override"><code> html,body {
  margin: 0;
  padding: 0;
 }
 .slider {
  width: 1024px;
  margin: 2em auto;

 }

 .slider-wrapper {
  width: 100%;
  height: 350px;
  position: relative;
 }

 .slide {
  float: left;
  position: absolute;
  opacity: 0;
  transition: opacity 1s linear;
 }

 .slider-wrapper > .slide:first-child {
  opacity: 1;
 }</code>```

<!DOCTYPE html>

 <button id="toggle">Pause</button>
 <button id="next">Next</button>
 <button id="previous">Previous</button>

```

There are other ways to do it, this seemed like a good approach based on your current codebase. Hope this helps.

Body:
Please see my code below. This code works fine but i want to add pause/resume,forward,backward buttons. So if someone click on pause, it will stop auto rotation. I can't use Jquery. I worked on this code but i am not able to add buttons to this code.

(function() {

    function Slideshow( element ) {
        this.el = document.querySelector( element );
        this.init();
    }

    Slideshow.prototype = {
        init: function() {
            this.wrapper = this.el.querySelector( ".slider-wrapper" );
            this.slides = this.el.querySelectorAll( ".slide" );
            this.previous = this.el.querySelector( ".slider-previous" );
            this.next = this.el.querySelector( ".slider-next" );
            this.index = 0;
            this.total = this.slides.length;
            this.timer = null;

            this.action();
            this.stopStart();
        },
        _slideTo: function( slide ) {
            var currentSlide = this.slides[slide];
            currentSlide.style.opacity = 1;

            for( var i = 0; i < this.slides.length; i++ ) {
                var slide = this.slides[i];
                if( slide !== currentSlide ) {
                    slide.style.opacity = 0;
                }
            }
        },
        action: function() {
            var self = this;
            self.timer = setInterval(function() {
                self.index++;
                if( self.index == self.slides.length ) {
                    self.index = 0;
                }
                self._slideTo( self.index );

            }, 3000);
        },
        stopStart: function() {
            var self = this;
            self.el.addEventListener( "mouseover", function() {
                clearInterval( self.timer );
                self.timer = null;

            }, false);
            self.el.addEventListener( "mouseout", function() {
                self.action();

            }, false);
        }

    };

    document.addEventListener( "DOMContentLoaded", function() {

        var slider = new Slideshow( "#main-slider" );

    });

})();

html,body {
    margin: 0;
    padding: 0;
}
.slider {
    width: 1024px;
    margin: 2em auto;

}

.slider-wrapper {
    width: 100%;
    height: 400px;
    position: relative;
}

.slide {
    float: left;
    position: absolute;
    width: 100%;
    height: 100%;
    opacity: 0;
    transition: opacity 3s linear;
}

.slider-wrapper > .slide:first-child {
    opacity: 1;
}

Body:
This can be done this way.

(function() {

    function Slideshow( element ) {
        this.el = document.querySelector( element );
        this.init();
    }

    Slideshow.prototype = {
        init: function() {
            this.wrapper = this.el.querySelector( ".slider-wrapper" );
            this.slides = this.el.querySelectorAll( ".slide" );
            this.index = 0;
            this.total = this.slides.length;
            this.timer = null;
   this.nextButton = document.querySelector('#next');
   this.previousButton = document.querySelector('#previous');
   this.toggleButton = document.querySelector('#toggle');
            this.action();
            this.stopStart();
   this.toggleButton.addEventListener('click', function(e){
    e.preventDefault();
    this.stop();
   }.bind(this));
   this.nextButton.addEventListener('click', function(e){
    e.preventDefault();
    this.next();
   }.bind(this));
   this.previousButton.addEventListener('click', function(e){
    e.preventDefault();
    this.previous();
   }.bind(this))
        },
        _slideTo: function( slide ) {
            var currentSlide = this.slides[slide];
            currentSlide.style.opacity = 1;

            for( var i = 0; i < this.slides.length; i++ ) {
                 slide = this.slides[i];
                if( slide !== currentSlide ) {
                    slide.style.opacity = 0;
                }
            }
        },
        action: function() {
            var self = this;
            this.timer = setInterval(function() {
                self.index++;
                if( self.index == self.slides.length ) {
                    self.index = 0;
                }
                self._slideTo( self.index );

            }, 5000);
        },
        stopStart: function() {
            var self = this;
            self.el.addEventListener( "mouseover", function(){
     clearInterval( self.timer );
     self.timer = null;
   }, false);
            self.el.addEventListener( "mouseout", function() {
                self.action();

            }, false);
        },
  stop: function(){
   if(this.timer){
    clearInterval( this.timer );
    this.timer = null;
    this.toggleButton.innerText = 'Play';
   }else{
    this.action();
    this.toggleButton.innerText = 'Pause';
   }

  },
  next: function(){
   this.index++;
   if( this.index === this.slides.length ) {
    this.index = 0;
   }
   this._slideTo(this.index);

  },
  previous: function(){
   this.index--;
   if( this.index <= 0 ) {
    this.index = this.slides.length - 1;
   }
   this._slideTo(this.index);
  }

    };
    document.addEventListener( "DOMContentLoaded", function() {

        var slider = new Slideshow( "#main-slider" );

    });

})();

 html,body {
  margin: 0;
  padding: 0;
 }
 .slider {
  width: 1024px;
  margin: 2em auto;

 }

 .slider-wrapper {
  width: 100%;
  height: 350px;
  position: relative;
 }

 .slide {
  float: left;
  position: absolute;
  opacity: 0;
  transition: opacity 1s linear;
 }

 .slider-wrapper > .slide:first-child {
  opacity: 1;
 }

<!DOCTYPE html>
<html>
<body>

<div class="slider" id="main-slider"><!-- outermost container element -->
    <div class="slider-wrapper"><!-- innermost wrapper element -->
        <img id="image1" src="http://placehold.it/350x250?text=1" alt="First" class="slide" /><!-- slides -->
        <img id="image2" src="http://placehold.it/350x250?text=2" alt="Second" class="slide" />
        <img id="image3" src="http://placehold.it/350x250?text=3" alt="Third" class="slide" />
    </div>
</div>
<div class="buttonBlock">
 <button id="toggle">Pause</button>
 <button id="next">Next</button>
 <button id="previous">Previous</button>
</div>
</body>
</html>

There are other ways to do it, this seemed like a good approach based on your current codebase. Hope this helps.


问:
Uses for Optional
Having been using Java 8 now for 6+ months or so, I'm pretty happy with the new API changes. One area I'm still not confident in is when to use Optional. I seem to swing between wanting to use it everywhere something may be null, and nowhere at all.

There seem to be a lot of situations when I could use it, and I'm never sure if it adds benefits (readability / null safety) or just causes additional overhead.

So, I have a few examples, and I'd be interested in the community's thoughts on whether Optional is beneficial.

1 - As a public method return type when the method could return null:

```<code>public Optional<Foo> findFoo(String id);
</code>```

2 - As a method parameter when the param may be null:

```<code>public Foo doSomething(String id, Optional<Bar> barOptional);
</code>```

3 - As an optional member of a bean:

```<code>public class Book {

  private List<Pages> pages;
  private Optional<Index> index;

}
</code>```

4 - In Collections:

In general I don't think:

```<code>List<Optional<Foo>>
</code>```

adds anything - especially since one can use filter() to remove null values etc, but are there any good uses for Optional in collections?

Any cases I've missed?

答:
I do not think that Optional is a general substitute for methods that potentially return null values.

The basic idea is: The absence of a value does not mean that it potentially is available in the future. It's a difference between findById(-1) and findById(67).

The main information of Optionals for the caller is that he may not count on the value given but it may be available at some time. Maybe it will disappear again and comes back later one more time. It's like an on/off switch. You have the "option" to switch the light on or off. But you have no option if you do not have a light to switch on.

So I find it too messy to introduce Optionals everywhere where previously null was potentially returned. I will still use null, but only in restricted areas like the root of a tree, lazy initialization and explicit find-methods.

Title: Uses for Optional

Body:
Having been using Java 8 now for 6+ months or so, I'm pretty happy with the new API changes. One area I'm still not confident in is when to use Optional. I seem to swing between wanting to use it everywhere something may be null, and nowhere at all.

There seem to be a lot of situations when I could use it, and I'm never sure if it adds benefits (readability / null safety) or just causes additional overhead.

So, I have a few examples, and I'd be interested in the community's thoughts on whether Optional is beneficial.

1 - As a public method return type when the method could return null:

public Optional<Foo> findFoo(String id);

2 - As a method parameter when the param may be null:

public Foo doSomething(String id, Optional<Bar> barOptional);

3 - As an optional member of a bean:

public class Book {

  private List<Pages> pages;
  private Optional<Index> index;

}

4 - In Collections:

In general I don't think:

List<Optional<Foo>>

adds anything - especially since one can use filter() to remove null values etc, but are there any good uses for Optional in collections?

Any cases I've missed?


问:
Bitbucket activity graph
I would like to know if there is a solution in Bitbucket similar to Github's graphs. For example, here are the ones for Node.js:

Contributions graph

Commits graph

I've done some research and I haven't found anything similar. Does anybody know if this kind of visualisation exists in a hidden place in Bitbucket? Or is there some 3rd party service which provides these kinds of graphs of a git repository?

答: Click on account at top-right corner -> integrations -> Awesome Graphs -> add</p>

Title: Bitbucket activity graph


问:
How expensive is it to dereference a pointer?
How expensive is it to perform the dereference operation on a pointer?

I can imagine that the memory transfer is somehow proportional to the object size, but I want to know how expensive the dereference operation part is.

答: The dereferencing of a pointer shouldn't be much more than copying an address to a (address)register. Thats all.</p>

OwnerDisplayName: Tunnuz

LastEditorDisplayName: ChrisN

OwnerDisplayName: EricSchaefer


问:
python 3 division using mysql response
I am new to programming python and have come across a problem. I am querying a mysql db which returns a value which i want to use by dividing the response by another number. I have the following code:

```<code>def sum_perchange_by_sector(dates, num):
   for row, in dates:
   cur = con.cursor()
   cur.execute("select sum(dbdev.perchange) from dbdev inner join symbol

    on dbdev.symbol_id = symbol.id where symbol.sector =
    'Industrials' and dbdev.price_date = %s;",(row))

    sumer=cur.fetchone()[0]
    print(type(sumer))
    print(type(num))
    av=sumer/num
    print(av)
</code>```

when i run the code i get the following output:

```<code><class 'NoneType'>
<class 'int'>
av=sumer/num
TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
</code>```

If i comment out the lines:

```<code>av=sumer/num
print(av)
</code>```

The output shows the types as

```<code><class 'float'>
<class 'int'>
</code>```

I don't understand how this type appears to change and why the division does not work?

答: It really should be impossible for those lines to make a difference. It's much more likely that 'sumer' is something different each time you run it - 'NoneType' would probably correspond to no result being returned from the query.</p>

Title: python 3 division using mysql response

Body:
I am new to programming python and have come across a problem. I am querying a mysql db which returns a value which i want to use by dividing the response by another number. I have the following code:

def sum_perchange_by_sector(dates, num):
   for row, in dates:
   cur = con.cursor()
   cur.execute("select sum(dbdev.perchange) from dbdev inner join symbol

    on dbdev.symbol_id = symbol.id where symbol.sector =
    'Industrials' and dbdev.price_date = %s;",(row))

    sumer=cur.fetchone()[0]
    print(type(sumer))
    print(type(num))
    av=sumer/num
    print(av)

when i run the code i get the following output:

<class 'NoneType'>
<class 'int'>
av=sumer/num
TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'

If i comment out the lines:

av=sumer/num
print(av)

The output shows the types as

<class 'float'>
<class 'int'>

I don't understand how this type appears to change and why the division does not work?


答:
It can be fixed in multiple ways. What i would do is to assign layout_weight tag to all 3 images in the horizontal linear layout . something like this.

```<code><LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/img1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/imgadd"
        android:layout_weight ="1"
        />

    <ImageView
        android:id="@+id/img2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight ="1"
        android:src="@drawable/imgadd"
        />

    <ImageView
        android:id="@+id/img3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight ="1"
        android:src="@drawable/imgadd"
        />

</LinearLayout>
</code>```

Also remove the gravity tag in all three image views .

Title: Horizontal LinearLayout inside Vertical LinearLayout

Body:
It can be fixed in multiple ways. What i would do is to assign layout_weight tag to all 3 images in the horizontal linear layout . something like this.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/img1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/imgadd"
        android:layout_weight ="1"
        />

    <ImageView
        android:id="@+id/img2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight ="1"
        android:src="@drawable/imgadd"
        />

    <ImageView
        android:id="@+id/img3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight ="1"
        android:src="@drawable/imgadd"
        />

</LinearLayout>

Also remove the gravity tag in all three image views .


答:
This expression

```<code>var enumerable = array as int[] ?? array.ToArray();
</code>```

Can never be null (according to Resharper), because if array is null - it will throw an exception, and ToArray is known by Resharper to never return null (there is special database of methods Resharper knows cannot return null, and you can mark your own with NotNull attribute).

If you are interested about that Resharper "database" (called external annotations, which is just xml file), here is the source where you can see:

```<code> <member
    name="M:System.Linq.Enumerable.ToArray``1(System.Collections.Generic.IEnumerable{``0})">
     <parameter name="source">
       <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
     </parameter>
     <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
</member>
</code>```

Where you can see that ToArray() is marked with NotNull attribute. Because of that, Resharper is sure ToArray() cannot return null (while in theory it could).

If you want to use your expression, you need to check array for null, like this (if you can use C# 6):

```<code>var enumerable = array as int[] ?? array?.ToArray() ?? new int[size];
</code>```

Or this:

```<code>var enumerable = array as int[] ?? (array != null ? array.ToArray() : new int[size]);
</code>```

Title: If the null-coalescing operator is supposed to protect against null values, why would Visual Studio or ReSharper suggest a possible null solution?

Body:
This expression

var enumerable = array as int[] ?? array.ToArray();

Can never be null (according to Resharper), because if array is null - it will throw an exception, and ToArray is known by Resharper to never return null (there is special database of methods Resharper knows cannot return null, and you can mark your own with NotNull attribute).

If you are interested about that Resharper "database" (called external annotations, which is just xml file), here is the source where you can see:

 <member
    name="M:System.Linq.Enumerable.ToArray``1(System.Collections.Generic.IEnumerable{``0})">
     <parameter name="source">
       <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
     </parameter>
     <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
</member>

Where you can see that ToArray() is marked with NotNull attribute. Because of that, Resharper is sure ToArray() cannot return null (while in theory it could).

If you want to use your expression, you need to check array for null, like this (if you can use C# 6):

var enumerable = array as int[] ?? array?.ToArray() ?? new int[size];

Or this:

var enumerable = array as int[] ?? (array != null ? array.ToArray() : new int[size]);


问:
ionic 2 Module index has not exported member SqlStorage
I am working with ionic 2 and  I have to work with SqlStorage to create queries but it is not imported.

I have this:

import {Storage, SqlStorage} from '@ionic/storage';

But it give me this error:

Typescript Error
Module '"/home/../node_modules/@ionic/storage/es2015/index"' has no exported member 'SqlStorage'.

My ionic version is this:

Cordova CLI: 6.4.0
Ionic Framework Version: 2.3.0
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
Ionic App Scripts Version: 1.1.4
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Linux 4.4
Node Version: v7.4.0
Xcode version: Not installed

Help me please

答:
I would try deleting your node_modules directory and then run npm install

This will rebuild your node_modules directory and hopefully work.


问:
Magento - Not able to display tier pricing in product view
I have a different price set for products based on customer group. I want to show both price's to the customer in case both of them apply in product list, view, related and upsell products.

I turned on template path hints to verify that prices for all views are being rendered from the same template file, which is as follows:

/app/design/frontend/default/my_theme/template/catalog/product

I can see tier pricing correctly in product list, related and upsell products, but NOT for product view.

After debugging for a while I have narrowed down the problematic part of catalog/product/price.phtml file as follows:

```<code><?php
    $_coreHelper = $this->helper('core');
    $_weeeHelper = $this->helper('weee');
    $_taxHelper  = $this->helper('tax');

    $_product = $this->getProduct();
    $_id = $_product->getId();
    echo 'Product Id: ' . $_id;
    $_weeeSeparator = '';
    $_simplePricesTax = ($_taxHelper->displayPriceIncludingTax() || $_taxHelper->displayBothPrices());
    echo 'Simple Price Tax: ' . $_simplePricesTax;
    $_minimalPriceValue = $_product->getMinimalPrice();
    echo 'Minimal Price Value: ' . $_minimalPriceValue;
    //$_minimalPriceValue = 41;
    $_minimalPrice = $_taxHelper->getPrice($_product, $_minimalPriceValue, $_simplePricesTax);
    echo 'Minimal Price: ' . $_minimalPrice;
    //$_minimalPrice = 41;
?>
</code>```

I have echoed all prices fetched from models above, and only in case of product view page the $_product->getMinimalPrice() above does not return anything, while it appears correctly on list, related and upsell products.

I cannot think of any reason for this. There are a few lines different in catalog.xml but I don't think they have anything to do with this. Besides, there are a couple of commented lines in the above code, where I have hard-coded the minimalPrice and minimalPriceValue variables. After doing that the price starts appearing in product view also. The Product id for all views including product view is also appearing correctly, so the product IS loaded at that time.

We are using a custom template, and I see that in default we are not having this problem. I am using Magento 1.4.1.1

答:
Did you say that what you are trying to do works 100% with a stock theme?  If so then you really should look at the differences between your custom theme and the default.  Also, you might want to look at any changes the developer made in app/code/community and app/code/local that are customizations for the theme.  There could be some conflict.

But if you can't find a difference maybe I can give a few hints as to why you might be seeing this behavior.  Sometimes the same model (and block) objects have different data in them when you are viewing on the category list page vs the product view page.  The reason is that backend queries to the database are different.  I did some work with the tiering system before and I remember that when you are looking at the catalog page, the pricing data actually comes from some catalogindex_* tables rather than the catalog_product_entity_* tables.  If I remember correctly, there are two tables that it queries, something like catalogindex_price and catalogindex_minimal_price.  But then when you are at the product view page the pricing data comes from the standard catalog_product_entity_* and catalog_product_entity_tier_price tables. Anyway, that probably doesn't solve your problem, but it might get you pointed in the right direction.  Good luck.

Body:
I have a different price set for products based on customer group. I want to show both price's to the customer in case both of them apply in product list, view, related and upsell products.

I turned on template path hints to verify that prices for all views are being rendered from the same template file, which is as follows:

/app/design/frontend/default/my_theme/template/catalog/product

I can see tier pricing correctly in product list, related and upsell products, but NOT for product view.

After debugging for a while I have narrowed down the problematic part of catalog/product/price.phtml file as follows:

<?php
    $_coreHelper = $this->helper('core');
    $_weeeHelper = $this->helper('weee');
    $_taxHelper  = $this->helper('tax');

    $_product = $this->getProduct();
    $_id = $_product->getId();
    echo 'Product Id: ' . $_id;
    $_weeeSeparator = '';
    $_simplePricesTax = ($_taxHelper->displayPriceIncludingTax() || $_taxHelper->displayBothPrices());
    echo 'Simple Price Tax: ' . $_simplePricesTax;
    $_minimalPriceValue = $_product->getMinimalPrice();
    echo 'Minimal Price Value: ' . $_minimalPriceValue;
    //$_minimalPriceValue = 41;
    $_minimalPrice = $_taxHelper->getPrice($_product, $_minimalPriceValue, $_simplePricesTax);
    echo 'Minimal Price: ' . $_minimalPrice;
    //$_minimalPrice = 41;
?>

I have echoed all prices fetched from models above, and only in case of product view page the $_product->getMinimalPrice() above does not return anything, while it appears correctly on list, related and upsell products.

I cannot think of any reason for this. There are a few lines different in catalog.xml but I don't think they have anything to do with this. Besides, there are a couple of commented lines in the above code, where I have hard-coded the minimalPrice and minimalPriceValue variables. After doing that the price starts appearing in product view also. The Product id for all views including product view is also appearing correctly, so the product IS loaded at that time.

We are using a custom template, and I see that in default we are not having this problem. I am using Magento 1.4.1.1


问:
How to run cucumber test with JUnit in Eclipse
When I try to run my cucumber test from eclips (mars) as a JUnit they just stops in the middle.

They work if I run them from maven.

Please see screen shot at:
https://snag.gy/oz5Pjv.jpg

If you got any ideas please let me know.

Best regards
Fredrik

答:
It turned out to be two problems.

1) From my test I executed code from within my app that called System.exit. Then I got a:
The forked VM terminated without saying properly goodbye. VM crash or System.exit called?
The solution for this was just not to test that part.
2) But the test did not get on to the next scenario, the reason for that was that I did not know that I could clean up before next scenario took place. I fixed this by adding a:
    @After
    public void after() throws Throwable
    {
        exitApplicationSupport.cleanUp();
    }

..and in cleanUp() i called:

frameFixture.cleanUp();

Perhaps this helps someone else.

Best regards
Fredrik