首页 > 解决方案 > 具有类实现接口的 C# 方法泛型

问题描述

更新:这不像我希望的那样工作,正如其他人在下面所说的那样,这不是一个真正有效的方法。将以另一种方式处理我需要的东西。

我创建了一个接口,其中包含一个使用泛型参数的方法,以及一个实现它的类。但是在类实现中,我收到一个错误,即类没有实现类上的成员。这似乎很奇怪。

interface InterfaceA
{
    String MethodA<T>(T obj);
}

public class ClassA : InterfaceA
{
    public String name { get; set; }

    public ClassA()
    {
        this.name = "My Name";
    }

    public String MethodA<ClassA>(ClassA aClass)
    {
        String result = aClass.name;    //ERROR IS ON THIS LINE
        return result;
    }   
}

public class ClassB : InterfaceA
{
    public String test1 { get; set; }

    public ClassB()
    {
        this.test1 = String.Empty;
    }

    public String MethodA<ClassB>(ClassB obj)
    {
        String result = obj.test1;
        return result;
    }
}

public class ClassC : InterfaceA
{
    public String test2 { get; set; }

    public ClassC()
    {
        this.test2 = String.Empty;
    }

    public String MethodA<ClassC>(ClassC obj)
    {
        String result = obj.test2;
        return result;
    }
}

这给出了“错误 CS1061 'ClassA' 不包含 'name' 的定义,并且找不到可访问的扩展方法 'name' 接受类型为 'ClassA' 的第一个参数”(您是否缺少 using 指令或程序集引用?) "

我确定我这里出了点问题,但我不确定它是什么。

标签: c#.netgenericsinterface

解决方案


该问题可能是由于您重新使用ClassA泛型类型的名称引起的。在这种情况下,这隐藏了 的真正定义ClassA。所以,为它使用另一个名字,这T在 C# 中很常见。现在它可以是任何类型,但如果你想确保它具有name属性,那么你需要一个泛型类型约束。例如,这将起作用:

interface InterfaceA
{
    string MethodA<T>(T obj) where T : ClassA;
                           //^^^^^^^^^^^^^^^^
}

public class ClassA : InterfaceA
{
    public String name { get; set; }

    public ClassA()
    {
        this.name = "My Name";
    }

    public string MethodA<T>(T aClass) where T : ClassA
                                     //^^^^^^^^^^^^^^^^

    {
        String result = aClass.name;
        return result;
    }
}

当然,现在和之间有一种奇怪的关系ClassAInterfaceA所以你可能想把这个name属性提取出来,因为它也是它自己的接口。例如:

public interface INamed
{
    string name { get; }
}

现在您的其他代码将如下所示:

interface InterfaceA
{
    string MethodA<T>(T obj) where T : INamed;
                           //^^^^^^^^^^^^^^^^
}

public class ClassA : InterfaceA, INamed
{
    public String name { get; set; }

    public ClassA()
    {
        this.name = "My Name";
    }

    public string MethodA<T>(T aClass) where T : INamed
                                     //^^^^^^^^^^^^^^^^

    {
        String result = aClass.name;
        return result;
    }
}

推荐阅读