Matt
Matt

Reputation: 1704

C# generic typing with a user defined class

I want to make code that is as DRY as possible. The architecture I'm using has various pieces of data: Channel, User, Process, etc. Each has a public Id string property. I'm currently abstracting out a lot of the business logic with:

using System;
using System.Collections.Generic;
using Vert.Slack;

namespace Vert.Interfaces
{
    public abstract class DataSource<T> : IDataSource<T>
    {
        protected Dictionary<string, T> _items;

        public DataSource()
        {
            _items = new Dictionary<string, T>();
        }

        public abstract bool Register(T item);

        public T LookupUsing<String>(string key)
        {
            T item = default(T);
            item = _items[key];
            return item;
        }

        public IEnumerable<T> List(int? limit)
        {
            List<T> items;

            if(!limit.HasValue)
            {
                items = new List<T>(_items.Values);
            }
            else
            {
                items = new List<T>(limit.Value);
                items.AddRange(_items.Values);
            }

            return items;
        }

        public abstract T LookupUsing<RtmEvent>(Slack.RtmEvent rtmEvent);

        public abstract T LookupUsing<Message>(Slack.Message message);
    }
}

I want to make Register generic, because I'm currently using this code on each of my classes that extends DataSource (where the only difference is Im, User, Channel, etc.) :

public override bool Register(Im im)
{
    if(!_items.ContainsKey(im.Id))
    {
        _items.Add(im.Id, im);
    }

    return true;
}

I'm currently running into problems because my first attempt was to change T to a new type I defined as IData:

namespace Vert.Data
{
    interface IData
    {
        string Id { get; set; }
    }
}

However this seems to confuse the compiler, because when I try to use the above Register in the new abstract DataSource class I get the compiler error:

'IData' does not contain a definition for 'Id' and no extension method 'Id' accepting a first argument of type 'IData' could be found (are you missing a using directive or assembly reference?)

There's gotta be a way to do this generically. What am I doing wrong?

Upvotes: 2

Views: 482

Answers (1)

Vir
Vir

Reputation: 652

You've just exchanged <T> with <IData>? That won't work as you've just changed name of generic type nothing more.

Instead try telling compiler that generic <T> should implement IData interface:

public abstract class DataSource<T> : IDataSource<T> where T : IData

Upvotes: 5

Related Questions