c# - C# 中的逆变

标签 c# inheritance interface contravariance

我有一个关于逆变接口(interface)的问题,我不确定解决它的最佳方法。这些是我的类(class):

public interface IObject {
}
public interface IBigObject : IObject {
}
public interface ISmallObject : IObject {
}
public class AnObject : IBigObject {

} 
public class DataWrapper<T> {
    public T Data { get; set; }
} 

我希望能够通过 DataWrapper<IObject> (可能是许多派生类)并以 IObject 的形式获取该项目,据我所知,我能做到这一点的唯一方法是这样的:

IObject itemToAdd = null;
if (values[1] is IObject) {
    itemToAdd = values[1] as IObject;
} else if (values[1] is DataWrapper<IObject>) {
    itemToAdd = ((DataWrapper<IObject>)values[1]).Data;
} else if (values[1] is DataWrapper<IBigObject>) {
    itemToAdd = ((DataWrapper<IBigObject>)values[1]).Data;
} else if (values[1] is DataWrapper<BigObjectBase>) {
    itemToAdd = ((DataWrapper<ObservableBigObject>)values[1]).Data;
} else if (values[1] is DataWrapper<ObservableBigObject>) {
    itemToAdd = ((DataWrapper<ObservableBigObject>)values[1]).Data;
} 

有没有更短的路?

最佳答案

C# 中的类不能有变化,因此您必须创建一个接口(interface),例如

public interface IObjectWrapper<out T> where T : IObject
{
    T Value { get; }
}

那么你应该可以做到

if(values[1] is IObjectWrapper<IObject>)
{
    itemToAdd = ((IObjectWrapper<IObject>)values[1]).Value;
}

如果你不想这样做,你可以使用反射:

Type t = values[1].GetType();
if(t.IsGenericType && 
    t.GetGenericTypeDefinition() == typeof(DataWrapper<>) && 
    typeof(IObject).IsAssignableFrom(t.GetGenericArguments()[0]))
{
    itemToAdd = (IObject)t.GetProperty("Data").GetValue(value[0], null)
}

关于c# - C# 中的逆变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16759030/

相关文章:

c# - 如何使用 LINQ 重命名列表中的重复项

c# - 如何在运行时使用错误提供程序以及关联任何控件以进行验证

ruby - 在 Ruby 中防止继承

c++ - 模拟进化类的最佳编程实践是什么?

java - 继承类的 ClasscastException

java - 如何更改实现接口(interface)的继承类的参数?

java - Java中有没有动态实现接口(interface)的方法?

c# - 打包/发布任务 Microsoft.Web.Publishing.Tasks.CreateProviderList 无法加载 Web 部署程序集

c# - 用于字符写入和读取的 UWP 串口通信(UWP 和 Arduino)

java - 在Java中使用继承时如何避免重复使用代码?