4

I am having an issue whereby I cannot use an objects method because of this error:

Does not contain a definition...and no extension method...

It is very related to this question. I am doing what is given as the answer in that question, but I am still getting this error.

namespace MyProject.ViewModel
{
    public class NetworkHealthViewModel : ViewModelBase
    {
        private IDataService _dataService;
        public ObservableCollection<NetworkBandwidthModel> NbicNetworkBandwidth
        public ObservableCollection<NetworkPortalStatusModel> NbicNetworkPortalStatus

        public NetworkHealthViewModel()
        {
            _dataService = new DataServiceNetworkHealth();
            NbicNetworkBandwidth       = new ObservableCollection<NetworkBandwidthModel>();
            NbicNetworkPortalStatus    = new ObservableCollection<NetworkPortalStatusModel>();
            _dataService.LoadChartItems(NetworkBandwidthLoaded, NetworkBandwidthLoadedFailed);
            _dataService.LoadPortalStatus(NetworkPortalStatusLoaded, NetworkPortalStatusLoadedFailed);
         }

The error lies at LoadPortalStatus(). LoadChartItems() is fine. NetworkBandwidthLoaded and NetworkPortalStatusLoaded are delegates.

NetworkPortalStatusLoaded is laid out pretty much the same as NetworkBandwidthLoaded:

private void NetworkPortalStatusLoaded(IEnumerable<ChartModel> portalStatItems) 
{
    NbicNetworkPortalStatus.Clear();

    var networkPortalItems = from item in portalStatItems
                             where ((NetworkPortalStatusModel)item).Unit == "Portal"
                             select item;

    foreach (var item in networkPortalItems)
    {
        NbicNetworkPortalStatus.Add((NetworkPortalStatusModel)item);
    }

    Message = "Network Portal details loaded";
}

My DataServiceNetworkHealth class is defined as:

namespace MyProject.DataServices
{
    public class DataServiceNetworkHealth : IDataService
    {
        private Action<IEnumerable<ChartModel>> _delagateSuccess;
        private Action<Exception> _delagateFail;
        private String _portalHtmlResponse;

        public void LoadChartItems(Action<IEnumerable<ChartModel>> success, Action<Exception> fail)
        {
          ....
        }

        public void LoadPortalStatus(Action<IEnumerable<ChartModel>> success, Action<Exception> fail)
        {
          ....
        }
    }
}

Method LoadChartItems() is defined in the interface IDataService, but LoadPortalStatus is not. Perhaps that's where the problem lies. There are other DataServiceX classes that do not use LoadPortalStatus.

I know this is a long post, but I thought better to give all info up front. :-) Thanks for any help!

Community
  • 1
  • 1
sshirley
  • 239
  • 2
  • 6
  • 19

3 Answers3

2

Your reference to _dataService is of the type IDataService, which means that you can only access members defined by this interface (or extension methods for said interfae). You mention that LoadPortalStatus isn't part of that interface and thus you cannot access it through the _dataService reference.

Updated based on comment: Let's look at another example. If you define a List<int> reference like this:

List<int> i = new List<int>();

you can access all the members of List<T>() and all the members of Object. However, if you change the reference to

IEnumerable<int> i = new List<int>();

the only accessible members through i are GetEnumerator which is defined on IEnumerable<T> and the members inherited from Object.

If you include the System.Linq namespace, you also get access to the numerous extension methods defined for IEnumerable<T>.

The static type of i determines which members are available through that reference.

Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
  • This may seem like a silly question, but are you saying that I cannot define additional methods in class MyClass (i.e. MyClass : IMyInterface) that were not defined in IMyInterface? Do I have to create an additional derived class for that? – sshirley May 08 '12 at 16:27
  • I'm saying that if you reference the instance through a specific interface then that is the contract that defines what part of the members of the instance you have access to. I.e. the interface and any extension methods defined for that interface is the members you can access (along with the members for Object of course). – Brian Rasmussen May 08 '12 at 16:36
  • I've updated my answer with another example. Hopefully that explains it a little better. – Brian Rasmussen May 08 '12 at 16:40
  • That totally makes sense. The reason I was calling private IDataService _dataService; was because using MVVM Light, one creates a class of a data service (of type IDataService) for production use and a class (again of type IDataService) for design time use. I hadn't implemented those methods in the design time class. Also since none of my other DataService classes were using those methods, I didnt think to include those methods in the IDataService. In the end, I simply made private IDataService _dataService; into private DataServiceNetworkHealth _dataService; Thanks much! – sshirley May 08 '12 at 17:38
0

If LoadPortalStatus is not available in the interface (or an extension method on that interface), then it can't be called from an instance of the interface.

Since you define:

private IDataService _dataService;

This means that you can only access things in _dataService declared in the IDataService (or as an extension method) interface, regardless of what the implementation of that interface is.

So your choices are:

1) make _dataService variable a type that has LoadPortalStatus defined. 2) add LoadPortalStatus to the IDataService interface. 3) Create an extension method for IDataService called LoadPortalStatus

Any of those would work, though 1 or 2 would probably be preferable, in my opinion.

James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
0

This might be overly obvious, but could you be getting this error because you don't actually have a LoadPortalStatus method in your code?

You have multiple LoadChartItems methods with identical signatures -- is it possible that one of these is supposed to be the LoadPortalStatus() method?

public void LoadChartItems(Action<IEnumerable<ChartModel>> success, Action<Exception> fail)
{
    ....
}

//Same signature as above - is this supposed to implement LoadPortalStatus??
public void LoadChartItems(Action<IEnumerable<ChartModel>> success, Action<Exception> fail)
{
    ....
}
James Johnson
  • 45,496
  • 8
  • 73
  • 110