繁体   English   中英

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

[英]How can I use the same function for different type parameters which have the same member?

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

你必须要么:

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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