【问题标题】:C# method: is there a parameter name to insert 'derived classname' generically?C# 方法:是否有一个参数名称可以插入“派生类名”?
【发布时间】:2015-11-10 08:56:04
【问题描述】:

我想创建一个基类Student,其中包含一个方法changeName。我希望studentclasses派生自基类Student,例如collegestudent等。我希望能够更改学生的姓名。

我有这个代码:

public abstract class Student
{
    public virtual void changeName(CollegeStudent s, string name)
    {
       s.firstName = name;
    }

    public abstract void outputDetails();
}

public class CollegeStudent : Student
{
    public string firstName;
    public string lastName;
    public string major;
    public double GPA;

    public override void outputDetails()
    {
        Console.WriteLine("Student " + firstName + ");
    }
}

我想知道是否可以将 public virtual void changeName 参数更改为接受来自 Student 的任何派生类的泛型参数。

这在 c# 中可行吗?

(类似这样:public virtual void changeName(Anyderivedclass s, string name)

【问题讨论】:

  • 是的,你可以在 C# 中使用泛型
  • 您的 firstnamelastname 也应该在基类中。这将是一个更好的结构,因为每个学生至少有一个名字
  • 谢谢大家。 Dhaval Patel:我将如何在这个例子中应用它?

标签: c#


【解决方案1】:

如果你稍微改变你的设计,事情就会变得容易得多。您似乎来自 Java 背景,所以让我们看看 C# 如何帮助您改进代码。

首先,将 FirstName/LastName 字段移至基类,因为任何注册的学生都必须提供这些字段。其次,C# 有一个叫做Properties 的特性(特别是在这里我们可以使用自动实现的属性,因为我们不需要验证),它基本上是get/set 方法的语法糖。您可以重新创建学生班级,使其如下所示:

public abstract class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

这将允许派生类的任何实例更改名字和姓氏属性,而无需添加任何额外的方法:

void Main()
{
    var student = new CollegeStudent();
    student.FirstName = "Yuval";
}

一般来说,您正在创建的对象上的任何实例方法都不应该接受它自己的类型来改变自己。

【讨论】:

  • 感谢您的意见!这似乎是我提出的逻辑问题的最佳解决方案,甚至为我提供了一些理论上的帮助,谢谢!
【解决方案2】:

但是 changeName() 是您的抽象学生的实例方法。你为什么要传入它的一个派生实例作为它的参数之一?

为什么需要泛型?它应该很简单......

public abstract class Student
{
    public abstract void changeName(string newName);

    public abstract void outputDetails();
}

public class CollegeStudent : Student
{
    public string firstName;
    public string lastName;
    public string major;
    public double GPA;

    public override void changeName(string newName)
    {
          firstName = newName;
    }

    public override void outputDetails()
    {
        Console.WriteLine("Student " + firstName + ");
    }
}

而事实上(如所指出的)基类中changeName()的存在表明name属性属于基类,所以应该如下...

public abstract class Student
{
    public string firstName;
    public string lastName;

    public virtual void changeName(string newName)
    { 
        firstName = newName;
    }

    public abstract void outputDetails();
}

public class CollegeStudent : Student
{
    public string major;
    public double GPA;

    public override void outputDetails()
    {
        Console.WriteLine("Student " + firstName + ");
    }
}

【讨论】:

  • 感谢您的回复!
猜你喜欢
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
  • 2019-02-18
相关资源
最近更新 更多