2

I wrote this code (Only the first line is important):

public void InsertIntoBaseElemList(ref List<XElem> List, XElem Element)
{
    for (int index = 0; index < List.Count; index++) {
        if (List[index].Position < Element.Position && index + 1 == List.Count) {
            List.Add(Element);
        } else if (List[index].Position > Element.Position) {
            List.Insert(index, Element);
        }
    }
}

This method basically inserts an element of type XElem into a list of type XElem.
(Both parameters must have the same type. XElem in this case)

I have multiple of these lists but they don't have the same Type.
In order to allow inserting elements of type YElem into a list of type YElem, I'd have to copy this method and change the parameter types.

Is it possible to write a single method which can handle multiple types as a parameter, which guaranties parameter 1 and parameter 2 to be of the same type?

I read about Generic Types, but I couldn't make it work.

5
  • A base class is not a generic, correct? Commented Jan 5, 2015 at 14:48
  • he's asking about a generic solution Commented Jan 5, 2015 at 14:50
  • 3
    As a side note, the ref you have there seems pointless. Commented Jan 5, 2015 at 14:53
  • Salvatore solved my issue. @Chris Why is the ref pointless? The list is a private List of the class. I though I always must use the ref keyword if a need a reference, even for reference types... Commented Jan 5, 2015 at 14:57
  • @NoelWidmer: No, ref is only "needed" for value types. Also the for loop doesn't make much sense IMO (see my answer for explanation)... Commented Jan 5, 2015 at 15:00

4 Answers 4

4

Assuming the types implement the same interface or base type, you can do the following:

public void InsertIntoBaseElemList<TElem>(ref List<TElem> List, TElem Element) where TElem : IElem {
    for (int index = 0; index < List.Count; index++) {
        if (List[index].Position < Element.Position && index + 1 == List.Count) {
            List.Add(Element);
        } else if (List[index].Position > Element.Position) {
            List.Insert(index, Element);
        }
    }
}

the where clause restricts the type that can be specified as a parameter, and allows you to access properties & methods of that type in the method.

Sign up to request clarification or add additional context in comments.

Comments

2

You want something like the following:

public void InsertIntoBaseElemList<T>(List<T> List, T Element) where T : IElem
{
    for (int index = 0; index < List.Count; index++)
    {
        if (List[index].Position < Element.Position && index + 1 == List.Count)
            List.Add(Element);
        else if (List[index].Position > Element.Position)
            List.Insert(index, Element);
    }
}

Using IElem as the interface defining Position and implemented by XElem and YElem.
If the Position is defined in a common base class you can also use that, e.g. where T : BaseElem.

The ref parameter is not needed as List<T> is a reference type.

According to your explanation the following could be an alternative approach to your problem, which is easier to understand/maintain IMO:

public void InsertIntoBaseElemList<T>(List<T> List, T Element) where T : BaseElem
{
    var index = List.FindIndex(i => i.Position > Element.Position);
    if (index < 0) // no item found
        List.Add(Element);
    else
        List.Insert(index, Element);
}

2 Comments

@ChrFin There are about 10 lists like prepared, ready, done, failed. Alle elements in these lists must have a specific order. Wich is represented as <b>Position</b>. When moving one element from one list to another I cannot add it to the end of the new list, that would break the order in the list. I must find the correct <b>Position</b> in the new list based on the other elements and insert the it right there.
@NoelWidmer: Now I understand, please have a look at my alternative approach, may you also like it more...
1

try this:

public void InsertIntoBaseElemList<T>(ref List<T> List, T Element)
 where T : BaseElem

assuming XElem and YElem inherits from BaseElem

Comments

1

Assuming that XElem is a user-created class, you can first create an interface called IElem, which holds the common properties of XElem and YElem (such as Position). Then make XElem and YElem implement the interface that you created, and on the signature of the method, use the interface instead of the concrete class. Example below:

public interface IElem
{
    int Position {get; set; }
}

public class XElem : IElem ...

public void InsertIntoBaseElemList(ref List<IElem> List, IElem Element)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.