C# 为什么Intellisense建议将此扩展方法用于VS2017中的所有类型?

C# 为什么Intellisense建议将此扩展方法用于VS2017中的所有类型?,c#,generics,intellisense,C#,Generics,Intellisense,我有一些密码 public interface ISettable<TValue> { } public class Control<TValue> : ISettable<TValue> { } public static class ControlExtensions { public static TControl Set<TControl, T>(this TControl control, T value) where TCo

我有一些密码

public interface ISettable<TValue>
{
}

public class Control<TValue> : ISettable<TValue>
{
}

public static class ControlExtensions
{
    public static TControl Set<TControl, T>(this TControl control, T value) where TControl : ISettable<T>
    {
        return control;
    }
}
公共接口是可连接的
{
}
公共类控件:ISettable
{
}
公共静态类控件扩展
{
公共静态TControl集(此TControl控件,T值),其中TControl:ISettable
{
返回控制;
}
}
在VS2015中,Intellisense并不建议对所有类型进行此扩展,但在VS2017中,建议对每种类型进行此扩展,即使是
对象

当类型未实现ISettable时,为什么建议使用此方法

Visual Studio 2017

Visual Studio 2015
您似乎对C#中的泛型类型有点困惑。您的
t值
类型(没有任何约束)与扩展方法中的
t
完全相同,您只是用不同的名称调用它(就像使用正式的方法参数一样)

您可以选择以下方法:

public static TControl Set<TControl, T>(this TControl control, T value)
    where TControl : ISettable<T>
然后,您已经在接口中声明了
Set
方法,使用该接口的开发人员将清除该方法

编辑:为了在支持多个接口的同时拥有一个流畅的接口,您可以显式声明接口方法,以便在调用扩展方法时“隐藏”它们(否则您将无法解决那里的重载),如下所示:

public interface ISettable<in T>
{
    void Set(T value);
}

public interface IClickable
{
    void Click();
}

public class Control<T> : ISettable<T>, IClickable
{
    void ISettable<T>.Set(T value) => throw new NotImplementedException();

    void IClickable.Click() => throw new NotImplementedException();
}

public static class FluentExtensions
{
    public static TControl Set<TControl, T>(this TControl source, T value)
        where TControl : ISettable<T>
    {
        source.Set(value);
        return source;
    }

    public static TControl Click<TControl>(this TControl source)
        where TControl : IClickable
    {
        source.Click();
        return source;
    }
}
new Control<int>().Set(4).Click();
new Control<String>().Click().Set("It works!");
公共接口是可连接的
{
无效集(T值);
}
可点击的公共接口
{
无效单击();
}
公共类控件:ISettable、IClicable
{
void ISettable.Set(T值)=>抛出新的NotImplementedException();
void IClickable.Click()=>抛出新的NotImplementedException();
}
公共静态类FluentExtensions
{
公共静态TControl Set(此TControl源,T值)
其中t控件:可安装
{
source.Set(值);
返回源;
}
公共静态TControl单击(此TControl源)
其中t控件:可单击
{
source.Click();
返回源;
}
}
然后您就可以添加任意数量的接口,并像这样使用它们:

public interface ISettable<in T>
{
    void Set(T value);
}

public interface IClickable
{
    void Click();
}

public class Control<T> : ISettable<T>, IClickable
{
    void ISettable<T>.Set(T value) => throw new NotImplementedException();

    void IClickable.Click() => throw new NotImplementedException();
}

public static class FluentExtensions
{
    public static TControl Set<TControl, T>(this TControl source, T value)
        where TControl : ISettable<T>
    {
        source.Set(value);
        return source;
    }

    public static TControl Click<TControl>(this TControl source)
        where TControl : IClickable
    {
        source.Click();
        return source;
    }
}
new Control<int>().Set(4).Click();
new Control<String>().Click().Set("It works!");
new Control()。设置(4)。单击();
新建控件()。单击()。设置(“它工作!”);

什么?你能详细说明你的问题吗,因为它们不是很清楚。这段代码对我有用,我试过做
var x=new Control().Set(1)没有任何问题。您能非常清楚地说明什么是意外的或令人困惑的行为吗?理想情况下,包括发生的任何错误消息等?1正常工作,我的坏,我希望设置(int值),实际设置(T值),但设置(“字符串”)不正常工作。但是我在IntelliSense对象类型列表中有一个扩展请添加一个完整的示例,不清楚什么是不起作用的。我想要fluent接口,C#有两种方式用于fluent接口,扩展和IControl。两种方法都是无效的。@B.Vandyshev您难道不能让
Set
方法返回相同的
ISettable
实例,或者在
控件中声明一个独立的方法,该方法返回
this
,以便有一个流畅的界面吗?我已经用一个例子更新了我的答案。关于类控制:ISettable,IClickable?@B.Vandyshev我已经用一个解决方案更新了我的答案,该解决方案适用于任意数量的附加接口,使用您在这里寻找的fluent模式。设置在FluetExtensions中等于我的fluent,并且在IntelliSence方面有一些问题,我更新我的问题