是否可以通过方法的名称约束类型

本文关键字:约束 类型 可以通过 方法 是否 | 更新日期: 2023-09-27 18:03:13

例如,类型AABBCC都有一个方法Close()。他们没有实现任何带有void Close()的接口。是否有可能根据具有称为Close的方法的类型进行类型约束?

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

是否可以通过方法的名称约束类型

你可以这样做:

class Abc
{
    public void Close()
    { }
}
interface IClosable
{
    void Close();
}
class AbcClosable : Abc, IClosable
{ }
class GenClosable<T> where T : IClosable
{ }

然后使用

var genClosable = new GenClosable<AbcClosable>();

或创建泛型扩展方法

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

则使用

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

对于我来说,解决方案应该基于聚合而不是继承。为什么?"它们是我无法编辑的类型"。我认为因为这个类型属于另一个开发者|公司|等等,并且继承增加了耦合,所以解决方案应该基于聚合。

请注意,AA, BBCC中的任何一个都可以是sealedsealed

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

您可以使用反射来测试对象是否有close方法,如果存在则调用该方法。

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

一般来说,你想避免反射,但如果你被迫使用你无法控制的麻烦类型,这可能是最好的选择。