在RoslynPad中使用Extension方法

时间:2016-11-04 19:26:45

标签: c# roslyn roslynpad

我尝试理解类似于此代码的扩展方法

var p = new Person("Tim");   
p.LastName = "Meier"; 

// reader.Get<bool>("IsDerivat");
var IsOlivia = p.Get<bool>("Olivia");   

这是我在RoslynPad内的代码:

public static class PersonExtensions
{
    public static T Get<T>(this Person person, string name)
    {
        return (T)person.NewFirstName(name);
    }
}

public class Person
{    
    public Person(string firstName)
    {
        this.FirstName = firstName;
    }

    public string FirstName {get; private set;}
    public string LastName {get; set;}

    public object NewFirstName(string name)
    {
        this.FirstName = name;
        return (object) this.FirstName;
    }        
}    

但是我得到了这个错误

  

错误CS1109:必须在顶级静态中定义扩展方法   类; PersonExtensions是一个嵌套类

我发现了这个问题extension-methods-must-be-defined-in-a-top-level-static-class-,答案很好。

添加namespace Foo返回

  

错误CS7021:无法在脚本代码中声明命名空间

似乎roslynpad在幕后添加了东西。 那么我怎样才能确保我的扩展方法是在顶级静态类中定义的?

2 个答案:

答案 0 :(得分:15)

RoslynPad使用Roslyn的script language syntax,它不允许类中的扩展方法(因为整个脚本实际上是一个类,而C#不允许嵌套类中的扩展)。

目前,您唯一的选择(除了引用包含使用#r指令的扩展类的已编译程序集之外)是将扩展作为顶级方法放在脚本中。例如:

public static T Get<T>(this Person person, string name)
{
    return (T)person.NewFirstName(name);
}

var p = new Person("Tim");   
p.LastName = "Meier"; 

var IsOlivia = p.Get<bool>("Olivia"); // works 

PS - 我是RoslynPad的作者。

答案 1 :(得分:0)

要被视为顶级课程,必须在namespace内定义课程。移动您的人员和声明; PersonExtensions类到命名空间,这将解决问题。

所以:

namespace MyPersonNamespace
{
    public static class PersonExtensions
    {
        public static T Get<T>(this Person person, string name)
        {
            return (T)person.NewFirstName(name);
        }
    }

    public class Person
    {    
        public Person(string firstName)
        {
            this.FirstName = firstName;
        }

        public string FirstName {get; private set;}
        public string LastName {get; set;}

        public object NewFirstName(string name)
        {
            this.FirstName = name;
            return (object) this.FirstName;
        }        
    }  
}