为什么使用默认接口方法而不是 class 字段?

Why is a default interface method used instead of a class field?

我有如下代码。与默认实现的接口。以及使用这个接口的用户。但是出于某种原因,在 switch 案例中,我的代码使用接口的默认实现来代替 class 实现。我应该更改什么才能在控制台中看到“Ben”?

namespace ConsoleApp1
{
    public interface IUser
    {
        // Interface with default implementation
        public string Name { get => "Tom"; }
    }

    // User using this interface
    public class BenUser : IUser
    {
        public string Name = "Ben";
    }

    public static class MainClass
    {
        public static void ShowName(IUser user)
        {
            switch (user.Name)
            {
                case "Ben": // I expected the code to run here
                    Console.WriteLine("Ben");
                    break;

                case "Tom": // But the code goes here
                    Console.WriteLine("Tom");
                    break;
            }
        }

        static void Main()
        {
            // Create a user with Name "Ben"
            var ben = new BenUser();
            ShowName(ben);  // In console i see "Tom" for some reason
        }
    }
}

我不明白为什么代码会这样。

如评论中所述,您需要在 class 中使用相同的形状来实现接口 - 作为 属性 和 get。

public interface IUser
{
    // Interface with default implementation
    public string Name { get => "Tom"; }
}

// User using this interface
public class BenUser : IUser
{
    public string Name { get => "Ben"; }
}

public static class MainClass
{
    public static void ShowName(IUser user)
    {
        switch (user.Name)
        {
            case "Ben": // I expected the code to run here
                System.Console.WriteLine("Ben");
                break;

            case "Tom": // But the code goes here
                System.Console.WriteLine("Tom");
                break;
        }
    }

    static void Main()
    {
        // Create a user with Name "Ben"
        var ben = new BenUser();
        ShowName(ben);  // In console i see "Tom" for some reason
    }
}

这是我的编辑,旨在展示一些更标准的做法,请通读评论,看看它是否使任何内容更加清晰。创建成员的标准做法是使用 accesslevel Type VariableName { get; set; }

namespace ConsoleApp1
{
    public interface IUser
    {
        //denotes that this is set by construction, cannot be set afterwards 
        public string Name { get; }
    }

    // User using this interface
    public class BenUser : IUser
    {
        // Standard 'getter' only member with a compiled return value
        public string Name
        {
            get
            {
                return "Ben";
            }
        }
    }

    public class User : IUser
    {
        // private settable string to use with construction
        private string _name;

        // constructor
        public User(string userName)
        {
           // sets the private variable to desired value
            _name = userName;
        }

        // public 'getter' that returns the set value
        public string Name
        {
            get
            {
                return _name;
            }
        }
    }

    public static class MainClass
    {
        public static void ShowName(IUser user)
        {
            Console.WriteLine(user.Name);
        }

        static void Main()
        {
            // Create a user with static Name "Ben"
            var ben = new BenUser();
            ShowName(ben);

            // Create a user with variable Name set as "Carl"
            var carl = new User("Carl");
            ShowName(carl);
        }
    }
}

IUser中的Name是一个属性,而BenUser中的Name是一个字段。使用您的代码,当我们执行 user.Name 时,它会调用 IUser 中定义的 get 方法,而不是从 BenUser 获取名称字段的值。这是修复错误的示例实现。

public class BenUser : IUser
{
    public string Name { get => "Ben"; }
}

我建议不要像你那样做,因为 Name 标识符已经模糊不清