简体   繁体   English

没有公共基类的泛型访问属性

[英]Access Property of Generic without common base class

I have two independent classes of a library which doesn't have the same base class, neither I can change the implementation of this classes.我有一个库的两个独立类,它们没有相同的基类,我也不能更改这些类的实现。

Imagine the classes look like this:想象一下这些类是这样的:

public class A {
     public int X { get; } = 1;
}

public class B {
     public int X { get; } = 2;
}

Now I want to create a generic class, which is either depending on A or on B and access the value of X in there.现在我想创建一个泛型类,它要么依赖于A要么依赖于B并在那里访问X的值。

So i did:所以我做了:

public class GenericClass<T> 
    /*where T : ?*/
{
    void Foo(T t) {
        int x = t.X; // is this possible and how? 
    }
}

If I would implement A and B on myself, I would define an Interface which implements the Property X , but I can't do this.如果我自己实现AB ,我会定义一个实现属性X的接口,但我不能这样做。 Is there any other way, without changing class A and B , to say that the Generic T has the Property X ?在不改变A类和BA情况下,有没有其他方法可以说通用T具有属性X
Another idea would be to make child classes of A and B which then implement the mentioned Interface, but I want to avoid this.另一个想法是创建AB子类,然后实现上述接口,但我想避免这种情况。

You can overload Foo to take either A or B :您可以重载Foo以获取AB

void Foo(A t)
{
  int x = t.X;
}

void Foo(B t)
{
  int x = t.X;
}

If you want to do it for every conceivable class that might have an X property then you'll need a reflection based solution.如果您想为每个可能具有X属性的类执行此操作,那么您将需要一个基于反射的解决方案。 For example:例如:

void Foo(object obj)
{
  var property = obj.GetType().GetProperty("X");
  if(property == null) throw new Exception();

  int x = (int)property.GetValue(obj);
}

NOTE: I've minimized the error handling here.注意:我已经最小化了这里的错误处理。 You'd need to handle the case where the property might not have a getter (rare) or where it doesn't return an int您需要处理属性可能没有 getter(罕见)或不返回int

If the number of classes is manageable then you could create an interface with the property, derive a new class and implement the interface, which won't require a change.如果类的数量是可管理的,那么您可以使用该属性创建一个接口,派生一个新类并实现该接口,这不需要更改。 For example:例如:

interface IMyStuff
{
  int X{get;}
}

class MyA : A, IMyStuff
{
}

class MyB : B, IMyStuff
{
}

Not you can have Foo accept the interface:不是你可以让 Foo 接受接口:

void Foo(IMyStuff stuff)
{
  int x = stuff.X
}

Another option is to use dynamic .另一种选择是使用dynamic

dynamic d;
d = t;         // here t can be an instance of A, or or B, or of anything that has X
int x = d.X;

dynamic essentially implements "duck typing": if a dynamic object g has a property X , then gX will retrieve it. dynamic本质上实现了“鸭子类型”:如果dynamic对象g具有属性X ,则gX将检索它。 This is an alternative to implementing reflection manually.这是手动实现反射的替代方法。

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

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