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方面有一些问题,我更新我的问题