加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

是否可以在C#中调用泛型参数的方法?

发布时间:2020-12-15 20:48:58 所属栏目:百科 来源:网络整理
导读:在C中,您可以从模板参数调用方法,如下所示: templateclass T class foo{ T t; t.foo();} 但在C#中,看起来这是不可能的: class fooT{ T t; public void foo() { t.foo(); // Generates a compiler error }}; 我想这在C#中可能是不可能的,是吗? 解决方法 是
在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)
}

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读