简体   繁体   中英

Can overloaded methods work with different types without having to cast in c#?

I have 3 simple classes for this example:

 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; }
}

I have a few simple Print methods that I'm overloading to take a specific type. Don't mind response write, it's only for displaying the goal which is to use properties on that type that are not in the base.

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

public void Print(F f)
{
    Response.Write(f.LastName);
}

I'm curious about how I can get these instructions to work without having to cast the type? In total, I have 4 seperate User s. Each goes through the same process. I'd love to have the code once, not 4 times. This code below will not compile because LastName is not on the User object.

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

It would be nice to keep the print logic separate from the entity itself (Separation of Concerns). I would create an IPrintable interface:

public interface IPrintable
{
    string Data { get; }
}

... and then implement that on the User class (making it abstract if you can)

public abstract class User : IPrintable
{
    public string FirstName { get; set; }
    public abstract string Data { get; }
}

Each subclass can then implement the 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; } }
}

... and whatever you use to print can just accept an IPrintable object

public void Print(IPrintable entity)
{
    Response.Write(entity.Data);
}

This has a number of advantages. Firstly, if you ever want to print any other kind of object (other than a User object) you could just have that object implement IPrintable . Nothing would need to change in your Print method.

Another advantage is that your Print method is now easily unit testable. You can simply pass in a mock IPrintable object when testing. Your unit test isn't dependent on any concrete implementation.

I think you should implement like this instead.

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);
}
}

I would make UserFactory return the correct type:

F f = UserFactory.GetF();

or:

F f;
UserFactory.Get<F>(out f);

Are you looking for something like this:

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();
            }
        }
    }

This uses method overriding so that each call automatically selects the appropriate method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM