将通用类型解析为其他通用类型

时间:2018-12-11 20:42:17

标签: c#

我创建了一个自定义词典,该词典以findSso(selectedVendor) { console.log('Got the selectedVendor as : ', JSON.parse(selectedVendor)); } 作为键,并以一个接口作为值。我想通过接口类型来标识接口,并且在该集合中应该只存在其中一个接口。我是通过创建此代码来实现的

Type

,我注意到我也可以将其用于其他代码位置。我需要将internal class ComponentCollection { public ComponentCollection() { components = new Dictionary<Type, IComponent>(); } private Dictionary<Type, IComponent> components; public void AddComponent<T>(T component) where T : IComponent { components.Add(typeof(T), component as IComponent); } public void RemoveComponent(Type componentType) { components.Remove(componentType); } public bool TryGetComponent<T>(out T component) { try { component = (T)components[typeof(T)]; return true; } catch (Exception) { component = default(T); return false; } } } 替换为通用类型。我从这里开始

IComponent

但是出现两个问题。

  1. internal class TypeCollection<V> { public TypeCollection() { items = new Dictionary<Type, V>(); } private Dictionary<Type, V> items; public void Add<T>(T value) where T : V { items.Add(typeof(T), value as V); } public void Remove(Type type) { items.Remove(type); } public bool TryGetValue<T>(out T value) { try { value = (T)items[typeof(T)]; return true; } catch (Exception) { value = default(T); return false; } } } 由于
  2. 而崩溃
  

type参数不能与'as'运算符一起使用,因为它可以   没有类类型约束或“类”约束

  1. items.Add(typeof(T), value as V);崩溃是因为
  

无法将类型转换为“ T”

是否可以修复它?

2 个答案:

答案 0 :(得分:2)

由于在where T : V上有约束Add,所以不需要使用as

public void Add<T>(T value) where T : V
{
    items.Add(typeof(T), value);
}

这也暗示了您需要对TryGetValue做些什么;添加约束:

public bool TryGetValue<T>(out T value) where T : V
{
    try
    {
        value = (T)items[typeof(T)];
        return true;
    }
    catch (Exception)
    {
        value = default(T);
        return false;
    }
}

请注意,您可以使用以下方法实现TryGetValue,而无需尝试捕获:

public bool TryGetValue<T>(out T value) where T : V
{
    if (items.TryGetValue(typeof(T), out var foundValue))
    {
        value = (T)foundValue;
        return true;
    }

    value = default(T);
    return false;
}

或更简洁(但可以说可读性更差):

public bool TryGetValue<T>(out T value) where T : V
{
    var found = items.TryGetValue(typeof(T), out var foundValue);
    value = found ? (T)foundValue : default(T);
    return found;
}

答案 1 :(得分:2)

如果绝对可以肯定要获得的东西是T,则可以通过以下方法将任何类型转换为通用类型参数:

T t = (T)(object)whatever;

但是,如果T是一种值类型,则这会带来拳击损失,这可能导致时空性能问题。 仔细跟踪您的效果,以查看此代码路径是否有可衡量的,有意义的影响

和往常一样,在拆箱时,必须确保类型完全匹配。例如,即使您可以将未装箱的整数转换为双精度,也不能将其拆箱。