tags:

views:

65

answers:

3

Basically, what I want to do, is:

public class MySpecialCollection<T>
    where T : ISomething { ... }

public interface ISomething
{
    public ISomething NextElement { get; }
    public ISomething PreviousElement { get; }
}

public class XSomething : ISomething { ... }

MySpecialCollection<XSomething> coll;
XSomething element = coll.GetElementByShoeSize(39);
XSomething nextElement = element.NextElement; // <-- line of interest

... without having to cast nextElement to XSomething. Any ideas? I would have wanted something in the kind of ...

public interface ISomething
{
    public SameType NextElement { get; }
    public SameType PreviousElement { get; }
}

Thank you in advance!

+1  A: 

Well, you can do it using an implicit operator (though I'm not 100% sure it will work in this case):

public static XSomething operator implicit(ISomething sth)
{
     return (XSomething)sth;
}

But note that this is clearly not a very good idea; the cleanest way is to do an explicit cast.

ShdNx
Okay, didn't think of that one. However, as you already stated, it is not a very clean solution (plus I would have to add this to every implementation of ISomething..) .. thanks anyway for the idea though :-)
Michael
+8  A: 

Make the interface generic:

public class MySpecialCollection<T> where T : ISomething<T> {
  ...
}

public interface ISomething<T> {
  T NextElement { get; }
  T PreviousElement { get; }
}

public class XSomething : ISomething<XSomething> {
  ...
}
Guffa
Kinda defeats the point of an interface, no? If you want to use this generic interface, you'll have to know what the implementing class is.
Bubblewrap
@Bubblewrap: The purpose is to make the interface return the implementing class, so you have to know the implementing class to use it anyway.
Guffa
@Guffa (and James, for that matter): I already considered this an option, I just hoped I could avoid the `public class XSomething : ISomething<XSomething>` construct - I'm kind of a database guy so redundant information hurts me :-/ But thank you both for the idea. I will evaluate the pros and cons of making the interface generic vs. casting the type.
Michael
@Michael: Yes, when the type of the collection is the same as the implementing type, it seems redundant. You can however make a `MySpecialCollection<Animal>` that contains `Cat` and `Dog` instances that inherit `Animal` and implements `ISomething<Animal>`.
Guffa
+1  A: 

I'd recommend making the interface generic so the types of the properties can be the interface's generic type.

using System;

namespace ConsoleApplication21
{
    public interface INextPrevious<out TElement>
    {
        TElement NextElement { get; }
        TElement PreviousElement { get; }
    }

    public class XSomething : INextPrevious<XSomething>
    {
        public XSomething NextElement
        {
            get { throw new NotImplementedException(); }
        }

        public XSomething PreviousElement
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class MySpecialCollection<T>
        where T : INextPrevious<T>
    {
        public T GetElementByShoeSize(int shoeSize)
        {
            throw new NotImplementedException();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var coll = new MySpecialCollection<XSomething>();
            XSomething element = coll.GetElementByShoeSize(39);
            XSomething nextElement = element.NextElement;
        }
    }
}
James Manning
looks like Guffa beat me to it :)
James Manning
See my comment on Guffas answer :-)
Michael