作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有一个通用的 class
有一个约束 where 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
这是您现有的 Watcher 类..
public class Watcher<T, TKey> : IWatcher<TKey> where T : IWatchable<TKey>
{
public Watcher(IWatchable<TKey> target) { }
}
这是它需要实现的接口(interface):
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
下一个技巧是依靠 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()));
这种方法可能不是您所要求的(或者您可能希望的),但我认为这是避免必须为许多常见情况显式指定类型的最佳方法。
关于c# - 避免显式泛型类型 c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39243423/
我是一名优秀的程序员,十分优秀!