在C中,您可以从模板参数调用方法,如下所示:
template<class T> class foo { T t; t.foo(); }
但在C#中,看起来这是不可能的:
class foo<T> { T t; public void foo() { t.foo(); // Generates a compiler error } };
我想这在C#中可能是不可能的,是吗?
解决方法
是的,如果您知道泛型类型占位符T从基类或接口实现成员,则可以使用where子句将类型T约束到该基类或接口.
public interface IFooable { void Foo(); } // ... public class Foo<T> where T : IFooable { private T _t; // ... public void DoFoo() { _t.Foo(); // works because we constrain T to IFooable. } }
这使得泛型类型占位符T可以被视为IFooable.如果不在泛型中约束泛型类型占位符,则它被约束为object,这意味着只有对象的成员对泛型可见(即,您只看到对象引用可见的成员,但调用任何被覆盖的成员将调用适当的覆盖).
注意:这是另外重要的,因为像运算符重载(请记住运算符被重载,而不是重写),所以如果您有这样的代码:
public bool SomeSuperEqualsChecker<T>(T one,T two) { return one == two; }
即使T是字符串,这也总是使用对象的==.但是,如果我们有:
public bool SomeSuperEqualsChecker<T>(T one,T two) { // assume proper null checking exists... return one.Equals(two); }
这个WOULD按预期使用字符串,因为Equals()被覆盖,而不是重载.
因此,长和短只是记住一个不受约束的通用占位符确实代表任何类型,但唯一可见的调用和操作是在对象上可见的.
除了接口/基类约束之外,还有一些其他约束:
> new() – 表示泛型类型占位符必须具有默认构造函数
> class – 表示泛型类型占位符必须是引用类型
> struct – 表示泛型类型占位符必须是值类型(枚举,基元,结构等)
例如:
public class Foo<T> where T : new() { private T _t = new T(); // can only construct T if have new() constraint } public class ValueFoo<T> where T : struct { private T? _t; // to use nullable,T must be value type,constrains with struct } public class RefFoo<T> where T : class { private T _t = null; // can only assign type T to null if ref (or nullable val) }
希望这可以帮助.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。