"Hiding" 在子 class 中具有非泛型方法的泛型方法

"Hiding" generic methods with nongeneric method in child class

我已经写了一些代码,我很好奇我正在做的事情是否存在我不知道的危险。

我已经尝试搜索,我发现的大多数问题都涉及如何使事情变得通用,这不是我的问题。我还查看了第 13.4.3 节下的 .net 4.5 的 C# 规范 - 通用方法和 7.5.2 关于类型推断,最后是 7.5.2.12 推断 return 类型,它们并没有真正涵盖我'我正在努力。

基本上我有一个 classes

的层次结构
public class SomeBaseClass { }
public class SomeClass : SomeBaseClass { }
public class AnotherClass : SomeBaseClass { }

public class BaseData
{
    public SomeBaseClass mMember;
    public BaseData() { }
    public TType GetMember<TType>()
        where TType : SomeBaseClass
    {
        return (TType)mMember;
    }
}

public class Data : BaseData
{
    public Data()
    {
        mMember = new SomeClass();
    }

    //Is this bad
    public SomeClass GetMember()
    {
        return base.GetMember<SomeClass>();
    }
}

编译器没有抱怨,因为我没有隐藏基础 class 方法。这表明智能感知将它们列为两个单独的方法。我已经编写了几个测试,它们的行为都符合我的预期,并且在查看 List<> 之类的东西时,有一些方法实例同时具有通用和非通用实现(例如来自 ParallelEnumerable 的 AsParallel),但不同之处在于在这种情况下,两种方法都存在于同一个 class 中,并分别采用通用和非通用参数。

下面列出了我 运行 的测试并按照我期望的方式显示了工作。

class Program
{
    static void Main(string[] args)
    {
        BaseData lData = new Data();
        Data lData2 = new Data();

        //Call base method with type
        SomeBaseClass lTest = lData.GetMember<SomeClass>();

        //Cast and call derived method
        SomeClass lTest2 = ((Data)lData).GetMember();

        //Call base method with type and then cast
        SomeClass lTest3 = (SomeClass)lData.GetMember<SomeBaseClass>();

        //Call derived method directly
        SomeClass lTest4 = lData2.GetMember();

        //Throw InvalidCastException
        SomeBaseClass lTest5 = lData2.GetMember<AnotherClass>();
    }
}

这样做的主要原因是,当 class 本身已经具有此信息时,我希望任何调用者代码都不必知道泛型类型。这是为了避免必须写

lData.GetMemberType<...>();

无处不在。

如果这个问题过于宽泛或过于武断,我深表歉意。大多数情况下,我只是想知道在这种情况下是否有任何东西无法像我想象的那样工作或有隐藏的错误等。

你的问题有点笼统,不好回答(你这是用来做什么的?这样设计的目的是什么?)。

我不认为名称重叠有什么问题,但它确实看起来像是设计有问题和泛型滥用的症状(所有转换应该让您了解这一点)。

理想情况下,您的 class 本身应该是泛型的,并且您应该始终使用泛型类型参数。这将使您免于正在进行的所有转换:

public class SomeBaseClass { }
public class SomeClass : SomeBaseClass { }
public class AnotherClass : SomeBaseClass { }

public class BaseData<TType> where TType : SomeBaseClass
{
    protected TType mMember;
    public BaseData() { }
    public BaseData(TType member)
        : this()
    {
        mMember = member;
    }

    public TType GetMember()
    {
        return mMember;
    }
}

public class Data : BaseData<SomeClass>
{
    public Data()
        : base(new SomeClass())
    {
    }

    // no need to implement GetMember(); base class has it covered
}