Использование методов расширения в 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 - это вложенный класс

Я нашел этот вопрос " методы расширения должны быть определены в статическом классе верхнего уровня", и ответы на него хорошие.

Добавление namespace Foo возвращается

ошибка CS7021: не удается объявить пространство имен в коде скрипта

Кажется, что roslynpad добавляет вещи за кулисы. Итак, как я могу убедиться, что мой метод расширения определен в статическом классе верхнего уровня?

2 ответа

Решение

RoslynPad использует синтаксис языка сценариев Roslyn, который не допускает методы расширения в классах (поскольку весь сценарий фактически является классом, а 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.

Чтобы считаться классом верхнего уровня, класс должен быть определен внутри namespace, Переместите объявления ваших классов Person & 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;
        }        
    }  
}
Другие вопросы по тегам