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

RoQ*_*riX 0 c# generics

我有一个库的两个独立类,它们没有相同的基类,我也不能更改这些类的实现。

想象一下这些类是这样的:

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

public class B {
     public int X { get; } = 2;
}
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个通用类,它要么依赖于AB与访问的价值X在那里。

所以我做了:

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

如果我自己实现Aand B,我会定义一个实现 Property 的 Interface X,但我不能这样做。有没有其他方法可以在不改变 class Aand 的情况B下说 GenericT有 Property X
另一个想法是使儿童类AB然后执行所提接口,但我想避免这种情况。

Sea*_*ean 5

您可以重载Foo以采取AB

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

void Foo(B t)
{
  int x = t.X;
}
Run Code Online (Sandbox Code Playgroud)

如果您想为每个可能具有X属性的类执行此操作,那么您将需要一个基于反射的解决方案。例如:

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

  int x = (int)property.GetValue(obj);
}
Run Code Online (Sandbox Code Playgroud)

注意:我已经最小化了这里的错误处理。您需要处理该属性可能没有 getter(罕见)或不返回int

如果类的数量是可管理的,那么您可以使用该属性创建一个接口,派生一个新类并实现该接口,这不需要更改。例如:

interface IMyStuff
{
  int X{get;}
}

class MyA : A, IMyStuff
{
}

class MyB : B, IMyStuff
{
}
Run Code Online (Sandbox Code Playgroud)

不是你可以让 Foo 接受接口:

void Foo(IMyStuff stuff)
{
  int x = stuff.X
}
Run Code Online (Sandbox Code Playgroud)