【问题标题】:replace inheritance with generic extension method用通用扩展方法替换继承
【发布时间】:2018-12-13 11:02:15
【问题描述】:

我创建了一个继承自 KeyedByTypeCollection 并对其进行扩展的类。

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.keyedbytypecollection-1?view=netframework-4.7.2

KeyedByTypeCollection 只有一个 Find 方法,如果没有找到项目,则返回 null。我更喜欢TryGetValue 方法,所以我添加了一个。

internal class TypeCollection<V> : KeyedByTypeCollection<V>
{
    public T ValueOrDefault<T>() where T : V
    {
        if (!Contains(typeof(T)))
        {
            return default(T);
        }

        return (T)this[typeof(T)];
    }

    public bool TryGetValue<T>(out T value) where T : V
    {
        if (!Contains(typeof(T)))
        {
            value = default(T);
            return false;
        }

        value = (T)this[typeof(T)];
        return true;
    }
}

问题是没有继承的理由。我只想扩展一个现有的类。我从这两种扩展方法入手

internal static class KeyedByTypeCollectionExtensions
{
    public static T ValueOrDefault<T>(this KeyedByTypeCollection<V> collection) where T : V
    {
        if (!collection.Contains(typeof(T)))
        {
            return default(T);
        }

        return (T)collection[typeof(T)];
    }

    public static bool TryGetValue<T>(this KeyedByTypeCollection<V> collection, out T value) where T : V
    {
        if (!collection.Contains(typeof(T)))
        {
            value = default(T);
            return false;
        }

        value = (T)collection[typeof(T)];
        return true;
    }
}

但是我该如何设置这些扩展方法呢?我必须为泛型类型V 设置什么?

【问题讨论】:

  • 您的实际实施有什么问题?为什么你更喜欢扩展方法?
  • @Sebi 因为在简单的扩展方法足够时扩展集合通常不是一个好主意。并且当前的扩展方法不会编译。
  • 好吧,我认为我应该更喜欢组合而不是继承,所以我想改为创建扩展方法

标签: c#


【解决方案1】:

您必须定义V

public static T ValueOrDefault<T,V>(this KeyedByTypeCollection<V> collection) where T : V

public static bool TryGetValue<T,V>(this KeyedByTypeCollection<V> collection, out T value) 
       where T : V

TryGetValue 可以很好地工作,因为编译器会知道使用了哪些类型,但是对于 ValueOrDefault,您必须设置这两种类型,这有点难看。

让我们考虑以下类:

public class A { }
public class B : A { }

那么用法可以是:

var myCollection = new KeyedByTypeCollection<A>();
myCollection.Add(new A());
myCollection.Add(new B());

myCollection.TryGetValue(out B b); // <-- Nice! :)
b = myCollection.ValueOrDefault<B,A>();  // <-- Ugly :(

【讨论】:

    猜你喜欢
    • 2014-02-15
    • 2017-03-16
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多