Question

For example, types AA, BB, and CC all have a method Close(). They do not implement any kind of interface with void Close() in it. Is it possible to do a type constraint based on the type having a method called Close?

public static void CloseThis<T>(this T openObject) where T : Closeable
{
    openObject.Close();
}
Was it helpful?

Solution

You can do something like this:

class Abc
{
    public void Close()
    { }
}

interface IClosable
{
    void Close();
}

class AbcClosable : Abc, IClosable
{ }

class GenClosable<T> where T : IClosable
{ }

then use

var genClosable = new GenClosable<AbcClosable>();

or create generic extension method

public static void CloseThis<T>(this T openObject) where T : Closeable
{
    openObject.Close();
}

then use it as

var abcClosable = new AbcClosable();
abcClosable.CloseThis();

OTHER TIPS

As for me, a solution should be based on aggregation not on inheritance. Why? "They are types I cannot edit". I think because this type belongs to another developer|company|etc and inheritance increases coupling, so the solution should be based on aggregation.

Please note, any of AA, BB or CC can be sealed or could be sealed

public sealed class Aa
{
    public void Close()
    {
    }
}

public interface IClosable
{
    void Close();
}

internal class AbcClosable : IClosable
{
    private readonly Aa _aa;

    public AbcClosable(Aa aa)
    {
        _aa = aa;
    }

    public void Close()
    {
        _aa.Close();
    }
}

public static class CloseableExtensions
{
    public static void CloseThis<T>(this T value)
        where T : IClosable
    {
        value.Close();
    }
}

You could use reflection to test if an object has a close method and then call it if it exists.

    static void CloseIfClosable(object o)
    {
        Type oType = o.GetType();
        MethodInfo closeMethod = oType.GetMethod("Close");
        if (closeMethod != null)
        {
            closeMethod.Invoke(o, new object[] { });
        }
    }

Generally speaking you want to avoid reflection but if you are being forced to use troublesome types outside your control it might be the best option.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top