Noel Widmer
Noel Widmer

Reputation: 4572

Create method with generic parameters

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.

Upvotes: 2

Views: 180

Answers (4)

scubaFun
scubaFun

Reputation: 1289

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)

Upvotes: 1

Allan Elder
Allan Elder

Reputation: 4094

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.

Upvotes: 4

Christoph Fink
Christoph Fink

Reputation: 23093

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);
}

Upvotes: 2

Salvatore Sorbello
Salvatore Sorbello

Reputation: 606

try this:

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

assuming XElem and YElem inherits from BaseElem

Upvotes: 1

Related Questions