在C#中的函数中访问泛型类型的属性

冰镇

我需要具有通用方法的接口。但是,该接口的每个实现都会知道其类型。

class Program
{
    static void Main(string[] args)
    {

        var specificContext = new SpecificContext();

        var res = new SrvThatCantBeGeneric().GetValueFromSpecificContext(specificContext);
        Console.WriteLine(res);
    }

}
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
    public int GetValueFromSpecificContext<SpecificContext>(SpecificContext specificContext)
    {
        return specificContext.MyProperty; // <-- this is where it breaks
    }
}

public interface ISrvThatCantBeGeneric
{        
    int GetValueFromSpecificContext<T>( T specificContext);
}

public class SpecificContext
{
    public int MyProperty { get; set; } = 42;
}

由于某种原因,当我以上述方式进行操作时,它不起作用并指出:

'SpecificContext'不包含'MyProperty'的定义,找不到可以接受的扩展方法'MyProperty'接受类型为'SpecificContext'的第一个参数(您是否缺少using指令或程序集引用?)

为什么会发生这种情况以及如何解决?

我可以通过移动通用类型的定义来修复它,如下所示:

public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric<SpecificContext>
{
    public int GetValueFromSpecificContext(SpecificContext specificContext)
    {
        return specificContext.MyProperty; // <-- this is where it breaks
    }
}

public interface ISrvThatCantBeGeneric<T>
{        
    int GetValueFromSpecificContext( T specificContext);
}

但这会破坏代码的其他部分,是行不通的。

编辑:简化我的代码

奥利维尔·罗吉尔(Olivier Rogier)

通过写:

public int GetValueFromSpecificContext<SpecificContext>(SpecificContext specificContext)

您“覆盖”作用域,这SpecificContext是一个通用类型参数,它会掩盖具有此名称的类,因此它与:

public int GetValueFromSpecificContext<T>(T specificContext)

也许您想写:

public interface ISrvThatCantBeGeneric
{
  int GetValueFromSpecificContext<T>(T specificContext) where T : SpecificContext;
}

public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
  public int GetValueFromSpecificContext<T>(T specificContext) where T : SpecificContext
  {
    return specificContext.MyProperty;
  }
}

public class SpecificContext
{
  public int MyProperty { get; set; } = 42;
}

public class SpecificContextChild : SpecificContext
{
  public SpecificContextChild()
  {
    MyProperty = 10;
  }
}

测试

var server = new SrvThatCantBeGeneric();
var context = new SpecificContextChild();
Console.WriteLine(server.GetValueFromSpecificContext(context));

输出量

10

您也可以将接口和类提升为泛型,而不是方法本身

如果相关:

public interface ISrvThatCantBeGeneric<T> where T : SpecificContext
{
  int GetValueFromSpecificContext(T specificContext);
}

public class SrvThatCantBeGeneric<T> : ISrvThatCantBeGeneric<T> where T : SpecificContext
{
  public int GetValueFromSpecificContext(T specificContext)
  {
    return specificContext.MyProperty;
  }
}

public class SpecificContext
{
  public int MyProperty { get; set; } = 42;
}

public class SpecificContextChild : SpecificContext
{

  public SpecificContextChild()
  {
    MyProperty = 10;
  }
}

var server = new SrvThatCantBeGeneric<SpecificContextChild>();
var context = new SpecificContextChild();
Console.WriteLine(server.GetValueFromSpecificContext(context));

另外,如果您喜欢或需要,可以使用接口代替基类

public interface IContext
{
  int MyProperty { get; set; }
}

非通用类版本:

public interface ISrvThatCantBeGeneric
{
  int GetValueFromSpecificContext<T>(T specificContext) where T : IContext;
}

public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
  public int GetValueFromSpecificContext<T>(T specificContext) where T : IContext
  {
    return specificContext.MyProperty;
  }
}

public class SpecificContext : IContext
{
  public int MyProperty { get; set; } = 42;
}

通用类版本:

public interface ISrvThatCantBeGeneric<T> where T : IContext
{
  int GetValueFromSpecificContext(T specificContext);
}

public class SrvThatCantBeGeneric<T> : ISrvThatCantBeGeneric<T> where T : IContext
{
  public int GetValueFromSpecificContext(T specificContext)
  {
    return specificContext.MyProperty;
  }
}

public class SpecificContext : IContext
{
  public int MyProperty { get; set; } = 42;
}

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在C#中访问非泛型类型

来自分类Dev

C#中的条件泛型类型构造函数?

来自分类Dev

在C#中检查T泛型类型具有属性S(泛型)

来自分类Dev

C#中泛型类型的缺点

来自分类Dev

C#中的泛型类型

来自分类Dev

在C#中循环泛型类型

来自分类Dev

C#中的泛型类型转换

来自分类Dev

C#中的双重泛型类型

来自分类Dev

我如何通过 C# 访问泛型类中的动态类属性?

来自分类Dev

从泛型类型中获取属性类型

来自分类Dev

访问泛型类型的属性

来自分类Dev

在C#中访问内部泛型的成员

来自分类Dev

C#中的泛型和继承类型

来自分类Dev

返回C#中作为集合的泛型类型

来自分类Dev

C#中的递归泛型类型参数

来自分类Dev

在c#中遍历泛型类型列表

来自分类Dev

比较C#中2个泛型类型的对象

来自分类Dev

在C#中强制转换为任何类型的泛型

来自分类Dev

C#泛型类型中的多态性

来自分类Dev

在 C# 中安全地转换泛型类型

来自分类Dev

C#覆盖泛型类中的基类属性

来自分类Dev

如何在C#中遍历泛型类的属性?

来自分类Dev

函数列表中的泛型类型

来自分类Dev

Haskell函数中的泛型与刚性类型

来自分类Dev

函数列表中的泛型类型

来自分类Dev

函数签名中的泛型类型

来自分类Dev

需要C#中的泛型构造函数

来自分类Dev

C#泛型并使用类型化方法中的非泛型版本

来自分类Dev

c#获取泛型类中泛型类型参数的名称