重载方法是否可以在不必在c#中强制转换的情况下处理不同的类型?

重载方法是否可以在不必在c#中强制转换的情况下处理不同的类型?,c#,C#,对于这个例子,我有3个简单的类: public class User { public string FirstName { get; set; } } public class E : User { public string MiddleInitial { get; set; } } public class F : User { public string LastName { get; set; } } 我有一些简单的打印方法,我正在重载这些方法以获取特定的

对于这个例子,我有3个简单的类:

 public class User
{
    public string FirstName { get; set; }
}

public class E : User
{
    public string MiddleInitial { get; set; }
}
public class F : User
{
    public string LastName { get; set; }
}
我有一些简单的打印方法,我正在重载这些方法以获取特定的类型。不要介意响应写入,它只用于显示目标,即在该类型上使用不在基中的属性

public void Print(E e)
{
    Response.Write(e.FirstName);
}

public void Print(F f)
{
    Response.Write(f.LastName);
}
我很好奇,我怎样才能让这些指令在不必转换类型的情况下工作?总共,我有4个独立的
User
s。每个过程都是一样的。我想要一次代码,而不是4次。下面的代码不会编译,因为
LastName
不在
User
对象上

User u = UserFactory.Get("f");
Print(u);

我会让UserFactory返回正确的类型:

F f = UserFactory.GetF();
或:

F;
UserFactory.Get(out f);

我会让UserFactory返回正确的类型:

F f = UserFactory.GetF();
或:

F;
UserFactory.Get(out f);

我认为您应该这样实现

void Main()
{
User u = UserFactory.Get("f");
u.Print();
}


public class User
{
public string FirstName { get; set; }

public virtual void Print()
{
    Response.Write(this.FirstName);
}
}

public class E : User
{
public string MiddleInitial { get; set; }

public override void Print()
{
    Response.Write(this.FirstName);
}
}
public class F : User
{
public string LastName { get; set; }

public override void Print()
{
    Response.Write(this.LastName);
}
}

我认为你应该这样实施

void Main()
{
User u = UserFactory.Get("f");
u.Print();
}


public class User
{
public string FirstName { get; set; }

public virtual void Print()
{
    Response.Write(this.FirstName);
}
}

public class E : User
{
public string MiddleInitial { get; set; }

public override void Print()
{
    Response.Write(this.FirstName);
}
}
public class F : User
{
public string LastName { get; set; }

public override void Print()
{
    Response.Write(this.LastName);
}
}

你在找这样的东西吗:

public class User
    {
        public string FirstName { get; set; }

        virtual public void Print()
        {
            Console.WriteLine(FirstName);
        }
    }

    public class E : User
    {
        public string MiddleInitial { get; set; }

        override public void Print()
        {
            Console.WriteLine(MiddleInitial);
        }
    }
    public class F : User
    {
        public string LastName { get; set; }

        override public void Print()
        {
            Console.WriteLine(LastName);
        }
    }

    internal class Program
    {
        public static void Main(string[] args)
        {
            var userArray = new User[3];

            userArray[0] = new User { FirstName = "John" };
            userArray[1] = new F { LastName = "Doe" };
            userArray[2] = new E { MiddleInitial = "K" };

            PrintUsers(userArray);
        }

        private static void PrintUsers(User[] userArray)
        {
            foreach (var user in userArray)
            {
                user.Print();
            }
        }
    }

这将使用方法重写,以便每次调用都自动选择适当的方法。

您是否正在寻找类似的方法:

public class User
    {
        public string FirstName { get; set; }

        virtual public void Print()
        {
            Console.WriteLine(FirstName);
        }
    }

    public class E : User
    {
        public string MiddleInitial { get; set; }

        override public void Print()
        {
            Console.WriteLine(MiddleInitial);
        }
    }
    public class F : User
    {
        public string LastName { get; set; }

        override public void Print()
        {
            Console.WriteLine(LastName);
        }
    }

    internal class Program
    {
        public static void Main(string[] args)
        {
            var userArray = new User[3];

            userArray[0] = new User { FirstName = "John" };
            userArray[1] = new F { LastName = "Doe" };
            userArray[2] = new E { MiddleInitial = "K" };

            PrintUsers(userArray);
        }

        private static void PrintUsers(User[] userArray)
        {
            foreach (var user in userArray)
            {
                user.Print();
            }
        }
    }

这将使用方法重写,以便每次调用都自动选择适当的方法。

最好将打印逻辑与实体本身分离(关注点分离)。我将创建一个
IPrintable
接口:

public interface IPrintable
{
    string Data { get; }
}
。。。然后在
User
类上实现它(如果可以的话,将其变成
abstract

然后,每个子类都可以实现
Data
getter

public class E : User
{
    public string MiddleInitial { get; set; }
    public override string Data { get { return MiddleInitial; } }
}

public class F : User
{
    public string LastName { get; set; }
    public override string Data { get { return LastName; } }
}
。。。无论您使用什么打印,都可以接受一个
IPrintable
对象

public void Print(IPrintable entity)
{
    Response.Write(entity.Data);
}
这有许多优点。首先,如果您想要打印任何其他类型的对象(而不是
用户
对象),您可以让该对象实现
IPrintable
。您的
打印方法不需要任何更改


另一个优点是,
Print
方法现在很容易进行单元测试。测试时,只需传入一个mock
IPrintable
对象。单元测试不依赖于任何具体的实现。

最好将打印逻辑与实体本身分离(关注点分离)。我将创建一个
IPrintable
接口:

public interface IPrintable
{
    string Data { get; }
}
。。。然后在
User
类上实现它(如果可以的话,将其变成
abstract

然后,每个子类都可以实现
Data
getter

public class E : User
{
    public string MiddleInitial { get; set; }
    public override string Data { get { return MiddleInitial; } }
}

public class F : User
{
    public string LastName { get; set; }
    public override string Data { get { return LastName; } }
}
。。。无论您使用什么打印,都可以接受一个
IPrintable
对象

public void Print(IPrintable entity)
{
    Response.Write(entity.Data);
}
这有许多优点。首先,如果您想要打印任何其他类型的对象(而不是
用户
对象),您可以让该对象实现
IPrintable
。您的
打印方法不需要任何更改


另一个优点是,
Print
方法现在很容易进行单元测试。测试时,只需传入一个mock
IPrintable
对象。单元测试不依赖于任何具体的实现。

有什么原因不能在用户上实现打印方法吗?子类可以适当地重写它。有什么原因不能在用户上实现打印方法吗?然后子类可以适当地重写它。工厂将根据输入字符串返回
new F()
new E()
。变量仍然声明为
User
。我理解,我是说我将通过添加重载来更改工厂,以显式地获得F或E,这也可以防止提供无效字符串。工厂将根据输入字符串返回
new F()
new E()
。变量仍然声明为
User
。我理解,我是说我将通过添加重载来更改工厂,以显式获得F或E,这也可以防止提供无效字符串。可以说这违反了可靠的原则,并且打印不是用户的功能。然而,你可以用扩展方法做类似的事情。它是如何违背坚实的原则的?似乎打印只用于用户对象,因此它属于用户。在我看来,打印使用响应对象,不管是什么,而且它可能打印一些用户不关心的内容、方式和目的。可以说,这违反了可靠的原则,打印不是用户的功能。然而,你可以用扩展方法做类似的事情。它是如何违背坚实的原则的?打印似乎只用于用户对象,因此它属于用户。在我看来,打印使用响应对象,不管是什么,而且它可能打印一些用户不关心的内容、方式和目的。它不使用重载,它使用重写。它不使用重载,它使用重写