繁体   English   中英

访问 c# 中的 function 中的泛型类型的属性

[英]Accessing property of generic type in a function in 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”的定义,并且找不到接受“SpecificContext”类型的第一个参数的可访问扩展方法“MyProperty”(您是否缺少 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);
}

但这在代码的另一部分中断,并且没有 go。

编辑:简化我的代码

通过写作:

public int GetValueFromSpecificContext<SpecificContext>(SpecificContext specificContext)

您“覆盖” scope ,这里的SpecificContext是一个通用类型参数,它掩盖了具有此名称的 class ,因此它与以下内容相同:

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));

Output

10

您也可以将接口和 class 提升为 generics,而不是方法本身

如果相关:

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));

此外,如果您喜欢或需要,您可以使用接口而不是基础 class

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

非通用 class 版本:

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;
}

通用 class 版本:

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM