如何对具有相同成员的不同类型参数使用相同的函数?

时间:2013-04-07 07:55:45

标签: c#

BHere是示例代码,我已经定义了两个类。如何使用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.
}

7 个答案:

答案 0 :(得分:5)

你必须要么:

  1. 使用Reflection获取属性(如果不存在则抛出)
  2. 有一个公共接口,例如INamed具有字符串Name属性,两个类中的每一个都实现
  3. 将局部变量声明为dynamic并使用它来访问Name属性(但实际上这与#1相同,因为动态分派仅使用Reflection来获取{{ 1}} property)。

答案 1 :(得分:5)

您可以利用dynamic绕过编译器,它会在运行时检查类型,因此您不需要强制转换:

void Output(dynamic obj)
{
    Console.WriteLine(obj.Name); 
}

答案 2 :(得分:5)

您应该声明一个接口,它将描述两个类的公共部分:

interface I
{
    string Name { get; set; }
    int Age { get; set; }
}

然后在AB

中实施它
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); 
}

答案 3 :(得分:2)

您可以使用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);
}

答案 4 :(得分:2)

您需要为这两个类创建一个公共接口,因此编译器知道这两个类都可以提供某些功能(在您的情况下为名称和年龄):

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

答案 5 :(得分:1)

在你的情况下 - B不是来自A,所以你不能将B投射到A.

将B更改为继承自A,例如

class B : A
{
...
}

另外 - 考虑你想要在B类的A()方法中完成什么。 并且 - 如果你继承了,你可能不需要两次声明相同的成员。

答案 6 :(得分:0)

你可以这样做:

if ( obj.GetType() == typeof( A ) )
{
    Console.WriteLine(((A)obj).Name);
}
else if ( obj.GetType() == typeof( B ) )
{
    Console.WriteLine(((B)obj).Name);
}