重载方法是否可以在不必在c#中强制转换的情况下处理不同的类型?
对于这个例子,我有3个简单的类:重载方法是否可以在不必在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; } } 我有一些简单的打印方法,我正在重载这些方法以获取特定的
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
方法现在很容易进行单元测试。测试时,只需传入一个mockIPrintable
对象。单元测试不依赖于任何具体的实现。最好将打印逻辑与实体本身分离(关注点分离)。我将创建一个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
方法现在很容易进行单元测试。测试时,只需传入一个mockIPrintable
对象。单元测试不依赖于任何具体的实现。有什么原因不能在用户上实现打印方法吗?子类可以适当地重写它。有什么原因不能在用户上实现打印方法吗?然后子类可以适当地重写它。工厂将根据输入字符串返回new F()
或new E()
。变量仍然声明为User
。我理解,我是说我将通过添加重载来更改工厂,以显式地获得F或E,这也可以防止提供无效字符串。工厂将根据输入字符串返回new F()
或new E()
。变量仍然声明为User
。我理解,我是说我将通过添加重载来更改工厂,以显式获得F或E,这也可以防止提供无效字符串。可以说这违反了可靠的原则,并且打印不是用户的功能。然而,你可以用扩展方法做类似的事情。它是如何违背坚实的原则的?似乎打印只用于用户对象,因此它属于用户。在我看来,打印使用响应对象,不管是什么,而且它可能打印一些用户不关心的内容、方式和目的。可以说,这违反了可靠的原则,打印不是用户的功能。然而,你可以用扩展方法做类似的事情。它是如何违背坚实的原则的?打印似乎只用于用户对象,因此它属于用户。在我看来,打印使用响应对象,不管是什么,而且它可能打印一些用户不关心的内容、方式和目的。它不使用重载,它使用重写。它不使用重载,它使用重写