如何对具有相同成员的不同类型参数使用相同的函数?
本文关键字:类型参数 函数 成员 | 更新日期: 2023-09-27 18:07:57
下面是示例代码,我定义了两个类。我如何使用Output
函数在两个不同的类中输出具有相同名称的成员?
class A
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public A(string name, int age, string email)
{
Name = name;
Age = age;
Email = email;
}
}
class B
{
public string Name { get; set; }
public int Age { get; set; }
public string Location { get; set; }
public B(string name, int age, string location)
{
Name = name;
Age = age;
Location = location;
}
}
void Output(object obj)
{
// How can I convert the object 'obj' to class A or class B
// in order to output its 'Name' and 'Age'
Console.WriteLine((A)obj.Name); // If I pass a class B in pararmeter, output error.
}
你必须:
- 使用反射来获取属性(如果不存在则抛出)
- 有一个共同的接口,如
INamed
有一个字符串Name
属性,这两个类都实现 - 声明一个局部变量为
dynamic
,并使用它来访问Name
属性(但实际上这与#1相同,因为动态调度将仅仅使用反射来获取Name
属性)。
您可以利用dynamic
绕过编译器,它在运行时检查类型,因此您不需要强制转换:
void Output(dynamic obj)
{
Console.WriteLine(obj.Name);
}
你应该声明一个接口来描述这两个类的公共部分:
interface I
{
string Name { get; set; }
int Age { get; set; }
}
然后在A
和B
中实现它:
class A : I
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public A(string name, int age, string email)
{
Name = name;
Age = age;
Email = email;
}
}
class B : I
{
public string Name { get; set; }
public int Age { get; set; }
public string Location { get; set; }
public B(string name, int age, string location)
{
Name = name;
Age = age;
Location = location;
}
}
和改变你的方法得到I
作为参数:
void Output(I obj)
{
Console.WriteLine(obj.Name);
}
您可以使用dynamic
、反射或继承。或者你可以复制这个方法并利用方法重载
void Output(A obj)
{
// in order to output its 'Name' and 'Age'
Console.WriteLine(obj.Age);
Console.WriteLine(obj.Name);
}
void Output(B obj)
{
// in order to output its 'Name' and 'Age'
Console.WriteLine(obj.Age);
Console.WriteLine(obj.Name);
}
您需要为这两个类创建一个公共接口,以便编译器知道这两个类可以提供某些特性(在您的例子中是Name和age):
interface IHasNameAndAge
{
string Name { get; }
int Age { get; }
}
class A : IHasNameAndAge
{
public string Name { get; set; }
public int Age { get; set; }
string Email { get; set; }
public A(string name, int age, string email)
{
Name = name;
Age = age;
Email = email;
}
}
class B : IHasNameAndAge
{
public string Name { get; set; }
public int Age { get; set; }
string Location { get; set; }
public A(string name, int age, string location)
{
Name = name;
Age = age;
Location = location;
}
}
void Output(IHasNameAndAge obj)
{
Console.WriteLine(obj.Name + " is " + obj.Age);
}
在您的例子中- B不继承A,因此您不能将B强制转换为A。
将B改为继承A,如
class B : A
{
...
}
还要考虑你想在B类的A()方法中完成什么。如果是继承的,则可能不需要两次声明相同的成员。
你可以这样做:
if ( obj.GetType() == typeof( A ) )
{
Console.WriteLine(((A)obj).Name);
}
else if ( obj.GetType() == typeof( B ) )
{
Console.WriteLine(((B)obj).Name);
}