扩展方法仅限于包含特定属性的对象

时间:2011-05-24 13:17:14

标签: c# .net generics

有没有办法创建一个扩展方法,其参数的唯一约束是具有特定命名的属性。 e.g:

public static bool IsMixed<T>(this T obj) where T:?
{
    return obj.IsThis && obj.IsThat;
} 

我试图将obj声明为动态,但不允许这样做。

4 个答案:

答案 0 :(得分:9)

此功能通常称为“鸭子打字”。 (因为当你调用foo.Quack()时,你所关心的只是它像鸭子一样嘎嘎作响。)非动态鸭子打字不是C#的一个功能,对不起!

如果确实没有关于参数的类型信息,您可以在C#4中使用dynamic:

public static bool IsAllThat(this object x)
{
    dynamic d = x;
    return d.IsThis || d.IsThat;
}

但最好是在编译时提出一些描述类型的接口或类似的东西。

答案 1 :(得分:2)

你必须得到T来实现一个接口,然后在约束中使用它。

答案 2 :(得分:2)

虽然您无法使用通用约束来执行您所期望的操作,但您可以使用反射在运行时检查类型以确定它是否具有这些属性并动态获取其值。

免责声明:我这样做是我的头脑,我可能会稍微偏离实施。

public static bool IsMixed(this object obj)
{
    Type type = obj.GetType();

    PropertyInfo isThisProperty = type.GetProperty("IsThis", typeof(bool));
    PropertyInfo isThatProperty = type.GetProperty("IsThat", typeof(bool));

    if (isThisProperty != null && isThatProperty != null)
    {
        bool isThis = isThisProperty.GetValue(this, null);
        bool isThat = isThatProperty.GetValue(this, null);

        return isThis && isThat;
    }
    else
    {
        throw new ArgumentException(
            "Object must have properties IsThis and IsThat.",
            "obj"
        );
    }
}

答案 3 :(得分:0)

实现此目的的唯一方法是将接口作为您要操作的类的基础:

interface iMyInterface
{

}

public static bool IsMixed<T>(this T obj) where T: iMyInterface
{
   return obj.IsThis && obj.IsThat;
} 
相关问题