避免显式泛型类型c#
假设我有一个泛型避免显式泛型类型c#,c#,generics,generic-constraints,C#,Generics,Generic Constraints,假设我有一个泛型类,该类有一个约束,其中T必须实现IWatchable,考虑到T无论如何都会提供该约束,那么有没有任何方法可以使用Watcher而不必显式声明TKey类型 public class Watcher<T, TKey> where T : IWatchable<TKey> { } public interface IWatchable<TKey> { TKey Key { get; } } 或 var-watcher=new-watch
类
,该类有一个约束,其中T
必须实现IWatchable
,考虑到T
无论如何都会提供该约束,那么有没有任何方法可以使用Watcher
而不必显式声明TKey
类型
public class Watcher<T, TKey> where T : IWatchable<TKey>
{
}
public interface IWatchable<TKey>
{
TKey Key { get; }
}
或
var-watcher=new-watcher();
公共类也被监视:IWatchable{…}
如果我理解正确,您基本上希望编译器从一个泛型类型推断出另一个泛型类型。通过使用静态泛型构造方法,您可以与此保持一定距离,但您必须妥协,让Watcher实现一个只有一个泛型类型param的接口。我将试着在下面举例说明,你可以决定是否值得做出妥协
这是您现有的Watcher类
public class Watcher<T, TKey> : IWatcher<TKey> where T : IWatchable<TKey>
{
public Watcher(IWatchable<TKey> target) { }
}
类型推断使我们不必显式地编写
var watcher = Watcher.For<int>(new BeingWatched(123));
如果不编译,您将得到错误
The type arguments for method 'Watcher.For<TKey>(IWatchable<TKey>)' cannot be inferred from the usage.
无法从用法推断方法“Watcher.for(IWatchable)”的类型参数。
您必须显式地指定
var watcher = Watcher.For<int>(new AlsoBeingWatched(123, Guid.NewGuid()));
var-watcher=watcher.For(new-AlsoBeingWatched(123,Guid.NewGuid());
或
var-watcher=watcher.For(new-AlsoBeingWatched(123,Guid.NewGuid());
这种方法可能不是您想要的(或者您希望的),但我认为这是避免为许多常见情况显式指定类型的最佳方法。考虑类型系统将允许类型多次实现泛型接口(使用不同的类型参数)@Damien_不信者因此如果
被监视
实现IWatchable
和IWatchable
,那么监视者将不知道在被监视
中使用哪个实现?这就是它需要显式的原因。where
子句只用于约束检查,不用于类型解析。。。但是,您是否需要在观察者
上了解T
?也许将一个观察者注册为public class watcher
并使用IWatchable
而不是具体的类型就足够了?有趣的解决方法,这看起来确实有些过分,但现在我明白了为什么必须明确声明该类型。谢谢你!
public static class Watcher
{
public static IWatcher<TKey> For<TKey>(IWatchable<TKey> target)
{
return new Watcher<IWatchable<TKey>, TKey>(target);
}
}
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()));