2

I've built a simplistic extension method, AddRange for ObservableCollection:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace Helpers
{

/// <summary>
/// Provides extension methods for the ObservableCollection<> class.
/// </summary>
public static class ObservableCollectionExtensions
{
    /// <summary>
    /// Adds a range of values to an ObservableCollection
    /// </summary>
    /// <typeparam name="T">The type of the collection.</typeparam>
    /// <param name="me">The observable collection to add values to.</param>
    /// <param name="values">The range of values to add.</param>
    public static void AddRange<T>(this ObservableCollection<T> me, IEnumerable<T> values)
    {
        foreach(var value in values)
        {
            me.Add(value);
        }
    }
}
}

I have created a test class (using MSTest) as follows:

using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.ObjectModel;
using Helpers;
namespace Helpers.Tests
{
[TestClass()]
public class ObservableCollectionExtensionsTests
{
    [TestMethod()]
    public void AddRangeTest()
    {
        ObservableCollection<string> coll = new ObservableCollection<string>();
        coll.Add("Hello");
        coll.Add("World");
        IEnumerable<string> range = new List<string>() { "This", "Is", "A", "Test" };
        coll.AddRange(range); //This is the line that fails
        Assert.AreEqual("hello world this is a test", String.Join(" ", coll).ToLowerInvariant());
    }
}
}

However when I try to build my project I get the following errors:

Error   Instance argument: cannot convert from 'System.Collections.ObjectModel.ObservableCollection<string>' to 'System.Collections.ObjectModel.ObservableCollection`1<string>' C:\TigerTMS\projects\Tests\Helpers\Extensions\ObservableCollectionExtensionsTests.cs

Error   'System.Collections.ObjectModel.ObservableCollection<string>' does not contain a definition for 'AddRange' and the best extension method overload 'iCharge.Helpers.ObservableCollectionExtensions.AddRange<T>(System.Collections.ObjectModel.ObservableCollection`1<T>, System.Collections.Generic.IEnumerable<T>)' has some invalid arguments  C:\TigerTMS\projects\Tests\Helpers\Extensions\ObservableCollectionExtensionsTests.cs

Error   The type 'System.Collections.ObjectModel.ObservableCollection`1<T0>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Windows, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.    C:\TigerTMS\projects\Tests\Helpers\Extensions\ObservableCollectionExtensionsTests.cs

The test project is in the same solution as the extension method and I'm able to use the extension method without problems in other projects in this solution. Additionally there are no warnings.

I've tried checking to make sure they all use the same version of .NET and that I'm not using some incorrect version of ObservableCollection from a different library, but that has had no effect and I can't think of where else to look next.

Edit: Under the build output, I get the following warnings:

7>------ Build started: Project: iChargeTests, Configuration: Debug Any CPU ------
7>  No way to resolve conflict between "System.Xml, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" and "System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". Choosing "System.Xml, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" arbitrarily.
7>  No way to resolve conflict between "System.ComponentModel.DataAnnotations, Version=5.0.5.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217" and "System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35". Choosing "System.ComponentModel.DataAnnotations, Version=5.0.5.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217" arbitrarily.
7>  No way to resolve conflict between "System.Runtime.Serialization, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" and "System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". Choosing "System.Runtime.Serialization, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" arbitrarily.
7>  No way to resolve conflict between "System.ServiceModel, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" and "System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". Choosing "System.ServiceModel, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" arbitrarily.

However since none of them are the namespace for ObservableCollection (System.Collections.ObjectModel), am I ok to ignore them?

Edit 2: Added a reference to System.Windows to my test project and added the line using System.Windows to the test class, and the errors remain.

Nick Udell
  • 2,420
  • 5
  • 44
  • 83
  • 2
    The last error seems pretty straightforward, you are missing a reference. Add that reference and see if your errors change (or disappear). – Matthijs Jun 26 '14 at 12:50
  • Under debug have you checked the assembly loading log messages? – Amir Abiri Jun 26 '14 at 12:50
  • You haven't added reference of actual project in your test project, – fhnaseer Jun 26 '14 at 12:50
  • There's definitely a reference to the actual project on my test project, additionally intellisense happily picks up my extension method inside the test class. – Nick Udell Jun 26 '14 at 12:53
  • @Matthijs but `ObservableCollection` doesn't exist in `System.Windows`, it's `System.Collections.ObjectModel` and `System.Windows` isn't referenced in my Helpers project either (which is where the extension method is defined, and which builds fine) – Nick Udell Jun 26 '14 at 12:57
  • Nonetheless, I tried adding a reference to System.Windows in my test project and 'using System.Windows' to my test class, but I still get the same errors. – Nick Udell Jun 26 '14 at 13:00
  • Even the reference error? – Matthijs Jun 26 '14 at 13:03
  • Add specific versions of your references, rather than relative onces. Click each reference that shows in your buildoutput and set their reference to specific. – Matthijs Jun 26 '14 at 15:10

1 Answers1

1

So I am dealing with the same problem (Generics: How to resolve conflicting ObservableCollection classes?), and I think I have at least a clue to why this isn't working. The solution I am pursuing isn't ideal, but might work for you as well.

First, the core issue: The ObservableCollection used by Silverlight is NOT the standard WPF one. If you look at the two assemblies, you'll see they have much different interfaces. Here is the one used by windows/the server:

Assembly System.dll, v4.0.30319

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Runtime;
using System.Runtime.CompilerServices;

namespace System.Collections.ObjectModel
{
    [Serializable]
    [TypeForwardedFrom("WindowsBase, Version=3.0.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
    public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
    {
        // Implementation
    }

Here is the version used by Silverlight:

Assembly System.Windows.dll, v4.0.30319
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;

namespace System.Collections.ObjectModel
{
    public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
    {
        // Implmentation
    }
}

It is therefore no wonder that they can't be converted. The solution I am pursuing is to instead create a separate object, which implements the core interfaces needed by both (Collection, INotifyCollectionChanged, INotifyPropertyChanged) and using that instead of the ObservableCollection class. Hopefully this helps you out a bit in finding a better solution. If you do, let me know!

Community
  • 1
  • 1
Aerophilic
  • 885
  • 2
  • 9
  • 22