避免显式泛型C#

奇异的

说我有一个泛型class该泛型T必须实现的地方有一个约束IWatchable<TKey>,是否有任何方法可以使用Watcher而不必显式声明TKey类型,而考虑T到无论如何都会提供这种类型

public class Watcher<T, TKey> where T : IWatchable<TKey>
{
}

public interface IWatchable<TKey>
{
    TKey Key { get; }
}

如果要使用,则无论如何Watcher class都必须将声明TKey为第二种类型。

var watcher = new Watcher<BeingWatched, int>();

public class BeingWatched : IWatchable<int> { ... }

或者

var watcher = new Watcher<AlsoBeingWatched<Guid>, Guid>();

public class AlsoBeingWatched<TKey> : IWatchable<TKey> { ... }
和罗伯茨

如果我理解正确,则本质上您是希望编译器从另一种推断出一种泛型类型。通过使用静态的泛型构造方法,您可以做到这一点,但是您必须妥协,并使Watcher <T,TKey>仅使用单个泛型类型参数实现接口。我将在下面尝试说明,您可以决定是否值得做出妥协。

这是您现有的Watcher类。

public class Watcher<T, TKey> : IWatcher<TKey> where T : IWatchable<TKey>
{
    public Watcher(IWatchable<TKey> target) { }
}

这是它需要实现的接口:

public interface IWatcher<TKey> { }

现在,我们需要一个非泛型的静态Watcher类,该类将包含一个仅需要一个类型参数的泛型方法:

public static class Watcher
{
    public static IWatcher<TKey> For<TKey>(IWatchable<TKey> target)
    {
        return new Watcher<IWatchable<TKey>, TKey>(target);
    }
}

请注意,类型签名将IWatcher <TKey>作为返回类型,即使它正在构造Watcher <IWatchable <TKey>,TKey>。这个技巧使我们仅可以指定一种类型的参数。

下一个技巧是依靠C#的类型推断,以便在调用“ For”方法时不必指定“ TKey”类型。如果我们上课:

public class BeingWatched : IWatchable<int>
{
    public BeingWatched(int key)
    {
        Key = key;
    }

    public int Key { get; }
}

那么我们可以使用以下代码为该实例获取观察者:

var watcher = Watcher.For(new BeingWatched(123));

类型推断使我们不必显式编写代码

var watcher = Watcher.For<int>(new BeingWatched(123));

只要没有歧义,这就是可行的。如果你有课

public class AlsoBeingWatched : IWatchable<int>, IWatchable<Guid>
{
    private readonly int _numberKey;
    private readonly Guid _guidKey;
    public AlsoBeingWatched(int numberKey, Guid guidKey)
    {
        _numberKey = numberKey;
        _guidKey = guidKey;
    }

    int IWatchable<int>.Key { get { return _numberKey; } }

    Guid IWatchable<Guid>.Key { get { return _guidKey; } }
}

然后

var watcher = Watcher.For(new AlsoBeingWatched(123, Guid.NewGuid()));

将无法编译,您将得到错误

The type arguments for method 'Watcher.For<TKey>(IWatchable<TKey>)' cannot be inferred from the usage.

您将必须明确指定其中一个

var watcher = Watcher.For<int>(new AlsoBeingWatched(123, Guid.NewGuid()));

或者

var watcher = Watcher.For<Guid>(new AlsoBeingWatched(123, Guid.NewGuid()));

这种方法可能不是您所要的(或者也许是您所希望的),但是我认为这是避免为许多常见情况明确指定类型的最佳方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

泛型与显式类型类/结构

来自分类Dev

Java泛型-构造函数调用的显式类型参数

来自分类Dev

Java泛型:显式检查原始类型

来自分类Dev

带where子句的泛型所需的显式强制转换

来自分类Dev

Java泛型-构造函数调用的显式类型参数

来自分类Dev

Java-泛型类的显式方法调用?

来自分类Dev

具有显式泛型行为的奇怪泛型方法调用

来自分类Dev

泛型类型的泛型构造函数的显式类型注释

来自分类Dev

C#泛型:通配符

来自分类Dev

C#泛型列表

来自分类Dev

C#:递归泛型

来自分类Dev

避免显式Lambda?

来自分类Dev

避免显式Lambda?

来自分类Dev

在C#中使用泛型和接口时如何避免强制转换

来自分类Dev

避免使用泛型方法设置类属性的递归性C#

来自分类Dev

为什么显式泛型函数值与类似的非泛型绑定不同?

来自分类Dev

C#中的泛型继承:无法将类型“ MyWidget”隐式转换为“ IWidget”

来自分类Dev

C#可以利用隐式嵌套的泛型参数吗?

来自分类Dev

C#可以利用隐式嵌套的泛型参数吗?

来自分类Dev

C#协方差泛型参数分配/广播(隐式转换)

来自分类Dev

C# 尝试返回泛型列表“不能隐式转换类型”

来自分类Dev

C#集合类型约束泛型

来自分类Dev

C#泛型,接口和继承

来自分类Dev

我在滥用C#泛型吗?

来自分类Dev

C#中的嵌套泛型问题

来自分类Dev

声明C#泛型类型方法

来自分类Dev

与C#泛型的协方差

来自分类Dev

C#泛型可以很棒吗?

来自分类Dev

C#中泛型类型的缺点