我已经为ASP.NET MVC ViewPage创建了一个扩展方法,例如:
public static class ViewExtensions
{
public static string Method<T>(this ViewPage<T> page) where T : class
{
return "something";
}
}
Run Code Online (Sandbox Code Playgroud)
从View(派生自ViewPage)中调用此方法时,我得到错误" CS0103:当前上下文中不存在名称'Method' "除非我使用this关键字来调用它:
<%: Method() %> <!-- gives error CS0103 -->
<%: this.Method() %> <!-- works -->
Run Code Online (Sandbox Code Playgroud)
为什么this需要关键字?或者没有它可以工作,但我错过了什么?
(我认为这个问题肯定有重复,但我找不到一个)
更新:
正如Ben Robinson所说,调用扩展方法的语法只是编译器糖.那为什么编译器不能自动检查当前类型的基类型的扩展方法而不需要this关键字?
我试图IEnumerable<Turtle>在一个派生自已实现的基类的类中实现IEnumerable<Animal>.
为什么base.Cast<Turtle>()在类的任何方法中调用(或基本元素上的任何LINQ方法)都Turtle无法编译?
不可能替换base,this因为它显然导致a StackOverflowException.
以下是复制问题的最小代码示例:
public interface IAnimal {}
public class Animal : IAnimal {}
public class Turtle : Animal {}
public class AnimalEnumerable : IEnumerable<Animal> {
List<Animal> Animals = new List<Animal>();
IEnumerator<Animal> IEnumerable<Animal>.GetEnumerator() {
return Animals.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return Animals.GetEnumerator();
}
}
public class TurtleEnumerable : AnimalEnumerable, IEnumerable<Turtle> {
IEnumerator<Turtle> IEnumerable<Turtle>.GetEnumerator() {
return base.Cast<Turtle>().GetEnumerator(); //FAILS WITH "CANNOT RESOLVE SYMBOL Cast"
}
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,更换base.Cast<Turtle>().GetEnumerator(); …
在使用实例成员时,我总是明确地使用我的代码,在它们前面this.加上静态成员,并在前面添加类型名称.
罗斯林似乎不喜欢这一点,并礼貌地建议你可以省略this.,并Type.从你的代码在适当情况下...
......所以我会这样做... (没有双关语意)
public void DoSomethingCool()
{
this.CallAwesomeMethod();
CoolCucumber.DoSomethingLessAewsome();
}
Run Code Online (Sandbox Code Playgroud)
... roslyn建议我这样做......
public void DoSomethingCool()
{
CallAwesomeMethod();
DoSomethingLessAwesome();
}
Run Code Online (Sandbox Code Playgroud)
...但是当谈到使用扩展方法时,似乎我不能省略this.例如...... 的使用
public int GetTotal()
{
// This doesn't work
return Sum(o => o.Value);
// This does
return this.Sum(o => o.Value);
}
Run Code Online (Sandbox Code Playgroud)
问题:
this.和Type.?this.用于扩展方法?this.和Type.和了StyleCop的分析仪坚持,我使用它们?我目前在System.Windows.Forms.Control上有一个扩展方法,如下所示:
public static void ExampleMethod(this Control ctrl){ /* ... */ }
Run Code Online (Sandbox Code Playgroud)
但是,此方法不会出现在从Control派生的类中,例如PictureBox.我是否可以创建一个不仅出现在Control中的扩展方法,而且对于从Control派生的类,而不必进行显式转换?
如果我实例化我的子类List<string>,那么我可以使用Linq的Select方法.
using System.Linq;
namespace LinqProblem
{
class Program
{
static void Main(string[] args)
{
BetterList list = new BetterList();
list.Select(l => l.ToString() == "abc"); // no compile error
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试在子类的定义中使用Select ...
using System.Collections.Generic;
using System.Linq;
namespace LinqProblem
{
class BetterList : List<string>
{
public List<string> Stuff
{
get
{
base.Select(l => l.ToString() == "abc"); // compile error
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
'
List<string>'不包含'Select'的定义.
为什么会出现这种情况,是否有解决方法?
我们使用生成代码的实用程序.我想扩展它,并认为我可以在不返回代码生成器的情况下完成它.这是问题所在.
代码生成器给了我:
public abstract class BaseService
{
protected virtual SqlCommand CreateSelectCommand(string whereClause, Hashtable parameters, string orderClause, int maxRows);
protected DataSet Fill(SqlCommand command);
}
Run Code Online (Sandbox Code Playgroud)
然后它会生成许多实现此类的类.例如
public class ChildService : BaseService
{
protected override SqlCommand CreateSelectCommand(string whereClause, Hashtable parameters, string orderClause, int maxRows)
{
//implementation here
}
protected override SqlCommand CreateSelectCommand(string whereClause, Hashtable parameters, string orderClause, int maxRows)
{
//implementation here
}
public virtual DataSet Select(string whereClause, System.Collections.Hashtable parameters, string orderClause, int maxRows)
{
SqlCommand command = CreateSelectCommand(whereClause, parameters, orderClause, maxRows);
return …Run Code Online (Sandbox Code Playgroud) c# ×6
.net ×2
c#-6.0 ×1
ienumerator ×1
inheritance ×1
intellisense ×1
interface ×1
linq ×1
roslyn ×1