【问题标题】:How to return generic type as an exact type based on the type of T in C#如何根据 C# 中 T 的类型将泛型类型返回为精确类型
【发布时间】:2019-05-08 22:24:26
【问题描述】:

我的作业 C# 代码有些问题。

问题:我创建了一个泛型方法,其返回类型为 T 和一个整数参数。该方法的作用如下: - 检查 T 的类型。 - 如果类型是 ClassA 那么它应该返回 ClassA 类型。 - 如果类型是 ClassB 那么它应该返回 ClassB 类型。 - 如果类型是 ClassC 那么它应该返回 ClassC 类型。

我可以用以下代码检查T的类型:

Type theType = typeof(T);

然后我检查:

if(theType.Equals(typeof(ClassA))
{
Return ClassA.FindByID(the given parameter);
}

但是,视觉工作室告诉我“不能将类型‘ClassA’隐式转换为‘T’。我试过演员就像 return (ClassA)blah blah blah; 但视觉工作室一直告诉我这个错误。

恐怕我会反过来做这整件事,我认为这本来可以做得更简单。那么,我怎样才能返回所需的类型呢?

感谢您的帮助。

PS.: 如有错误请见谅。我不是以英语为母语的人,这是我第一次使用 StackOverflow :)

我尝试过像这样明确地转换它:

return (ClassA) ClassA.FindById(Id);

但是我收到了上面提到的同样的错误信息。

这是我的完整方法。

public T GetById<T>(int Id)
{
   Type elementType = typeof(T);

   if(elementType.Equals(typeof(ClassA))
   {
      return ClassA.FindById(Id);
   }

   if(elementType.Equals(typeof(ClassB))
   {
      return ClassB.FindById(Id);
   }

   if(elementType.Equals(typeof(ClassC))
   {
      return ClassC.FindById(Id);
   }
}

【问题讨论】:

  • 编译器是正确的。您没有提供任何类型约束,因此它无法知道 TClassA 等是否可以相互转换。你为什么要使用这样的代码呢?你想做什么?与直接调用 Find 方法相比,此代码没有任何好处。
  • 这里的另一个问题是静态方法的使用。如果您没有使用静态方法,则根本不需要检查类型。您可以在每个类中实现例如IFinder 接口并直接调用其FindById 方法。
  • @ilkerkaran 这里没有对象实例。 OP 正在尝试基于类型调用静态方法。
  • @PanagiotisKanavos 你对构图和我之前的评论都是正确的。
  • 让我更详细地解释我的问题,为什么我首先要尝试这样做:数据层中有一个带有 EntityFramework 的 localDB。我在 Repo 层为所有实体创建了一个 Repository 类,其中包含 CRUD 方法。我还为 DBModel 创建了一个 Repository 类。我打算将此 DBModelRepo 用作所有 EntityRepos 的“领导者”类。因此,在 BusinessLogic 层,我需要做的就是使用正确的实体类型调用 ModelRepo 的 GetById 方法(问题中的方法),这个方法应该给我实体。

标签: c# visual-studio generics types


【解决方案1】:

这看起来更像是一个接口实现问题,而不是泛型类型问题。考虑一下,如果你有一个接口 IEntity,你会指定它必须有一个函数“IEntity FindById(int Id)”。然后,您将在 ClassA、ClassB 和 ClassC 中实现该函数(看起来您已经拥有)。

我不知道您在哪里实现了 FindById(int id),但在我看来,您需要做的就是在界面中包含该方法:

public interface IEntity
{
    IEntity FindById(int Id);
}

public class ClassA : IEntity
{
    IEntity IEntity.FindById(int Id)
    {
        IEntity returnvalue = null;

        //do some specific stuff to get the entity
        return returnvalue;
    }
}

public class ClassB : IEntity
{
    IEntity IEntity.FindById(int Id)
    {
        IEntity returnvalue = null;

        //do some specific stuff to get the entity
        return returnvalue;
    }
}

public class ClassC : IEntity
{
    IEntity IEntity.FindById(int Id)
    {
        IEntity returnvalue = null;

        //do some specific stuff to get the entity
        return returnvalue;
    }
}

public static class TestClass
{
    public static void Test()
    {
        IEntity EA = new ClassA();
        IEntity EB = new ClassB();
        IEntity EC = new ClassC();

        EA.FindById(1);
        EB.FindById(2);
        EB.FindById(3);
    }
}

通过这种方式,您实际上并没有键入检查任何内容。

【讨论】:

    【解决方案2】:

    好的。所以我发现我需要创建一个接口,然后在 ClassA 和 ClassB 中实现它。这样我就删除了问题中提到的错误。 我的代码现在看起来像这样:

    public ClassA : IEntity
    
    public ClassB: IEntity
    
    public ClassC: IEntity
    
    public IEntity FindById<T>(int ID)
    {
       Type elementType = typeof(T);
    
       if(elementType.Equals(typeof(ClassA))
       {
          return ClassA.FindById(ID);
       }
    
       if(elementType.Equals(typeof(ClassB))
       {
          return ClassB.FindById(ID);
       }
    
       if(elementType.Equals(typeof(ClassC))
       {
          return ClassC.FindById(ID);
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-30
      • 2016-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-11
      相关资源
      最近更新 更多