簡體   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