C# 如何访问对象';共享同一接口的对象列表中的特定属性

C# 如何访问对象';共享同一接口的对象列表中的特定属性,c#,C#,我有一个应用程序,其中有10个不同类型的对象。我希望将它们放在同一个列表中,并在许多场合重复它们。我不能把它们放在一个列表中,因为它们是不同类型的。所以我创建了一个接口并创建了一个所有对象共享的属性。现在我有了对象列表,列表的类型是“接口”。当我遍历对象时,我无法访问对象的特定属性,因为编译器只在运行时知道它是什么对象。所以,如果我试图编码Object_A.Name,VisualStudio将显示错误,因为它不知道对象的类型。很明显,我可以用if-else或类似的方法来找到对象的类型并进行转换,

我有一个应用程序,其中有10个不同类型的对象。我希望将它们放在同一个列表中,并在许多场合重复它们。我不能把它们放在一个列表中,因为它们是不同类型的。所以我创建了一个接口并创建了一个所有对象共享的属性。现在我有了对象列表,列表的类型是“接口”。当我遍历对象时,我无法访问对象的特定属性,因为编译器只在运行时知道它是什么对象。所以,如果我试图编码Object_A.Name,VisualStudio将显示错误,因为它不知道对象的类型。很明显,我可以用if-else或类似的方法来找到对象的类型并进行转换,但我想知道有没有更好的方法,或者这个拥有接口的方法是否是错误的,我是否应该从另一个方向开始

在下面的代码中,我想获得Devname,但我不能,因为它不是接口的一部分,而是属于每个对象。我可以让它成为接口的一部分,但有时我可能需要获得一个特定的属性。因此,我想知道是否有办法做到这一点

foreach (ICommonDeviceInterface device in Form1.deviceList)
{
if (device.DevName.Equals(partnername))
{
return device.Port[portNo].PortRef;
}
}
使用“as”和“is”了解什么类型的接口

public class A : ICommonDeviceInterface 
{
  public int AMember;
}
public class B :ICommonDeviceInterface 
{
  public int BMember;
}

foreach (ICommonDeviceInterface device in Form1.deviceList)
{

    if(device is A)
    {
       A a = device as A;
       a.AMember = 100;
    }
    else if(device is B)
    {
       B b = device as B;
       b.BMember = 123;
    }
}

一种方法是使用反射尝试从对象获取命名属性的属性值,方法如下:

public static object GetPropValue(object src, string propName)
{
    return src?.GetType().GetProperty(propName)?.GetValue(src, null);
}
上述代码的贷方为:

这不需要检查类型或强制转换,它只返回属性的值,如果不包含属性,则返回
null

在使用中,它可能看起来像:

private static void Main()
{
    // Add three different types, which all implement the same interface, to our list
    var devices = new List<ICommonDeviceInterface>
    {
        new DeviceA {DevName = "CompanyA", Id = 1},
        new DeviceB {DevName = "CompanyB", Id = 2},
        new DeviceC {Id = 3},
    };

    var partnerName = "CompanyB";

    foreach (var device in devices)
    {
        // Try to get the "DevName" property for this object
        var devName = GetPropValue(device, "DevName");

        // See if the devName matches the partner name
        if (partnerName.Equals(devName))
        {
            Console.WriteLine($"Found a match with Id: {device.Id}");
        }
    }
}

听起来像是你想要的。我找不到一个和你一样好的问题,希望其他人可以你能举一个具体的例子说明你想做什么吗?你怎么知道你要呼叫哪家酒店?您可以使用反射来尝试按名称访问属性,但我想知道是否有更好的设计来执行您尝试执行的任何操作。我有许多对象,需要处理它们。它们都有或多或少相同的方法,但方法中的代码可能会有所不同。所以我需要调用所有对象并调用某些方法。有些对象将具有相同的方法,有些对象可能具有比其他对象更多的方法,有些对象可能具有更少的方法。我在考虑一个未来的观点,当我可能只需要对其中一些对象进行处理时,但我希望一个列表包含所有对象。我对c#很陌生,但我非常积极地研究它,任何方向都会受到欢迎。谢谢。“我当然可以用if-else或类似的方法来找到对象的类型并进行投射,但我想知道有更好的方法”我以前就想到过反射。我在某处读到这是一项昂贵的手术。我真的不知道相对来说有多贵。如果我在循环中的150个对象上运行此方法,我不确定它是否对性能有显著影响。我的意思是,我更喜欢在这里问,如果是这样的话?不过,这个解决方案对我来说很好。谢谢,问得好。你必须试试看,并与你正在尝试的任何其他解决方案进行比较。好的是,对于添加到列表中的每个新类型,您不必添加新的
else if
interface ICommonDeviceInterface
{
    int Id { get; set; }
}

class DeviceA : ICommonDeviceInterface
{
    public int Id { get; set; }
    public string DevName { get; set; }
}

class DeviceB : ICommonDeviceInterface
{
    public int Id { get; set; }
    public string DevName { get; set; }
}

class DeviceC : ICommonDeviceInterface
{
    public int Id { get; set; }
}