GVKun编程网logo

泛型(Generic Type)新技术——C#中的类型参数(Type Parameter)(c#泛型类的作用)

14

在本文中,我们将带你了解泛型(GenericType)新技术——C#中的类型参数(TypeParameter)在这篇文章中,我们将为您详细介绍泛型(GenericType)新技术——C#中的类型参数(

在本文中,我们将带你了解泛型(Generic Type)新技术——C#中的类型参数(Type Parameter)在这篇文章中,我们将为您详细介绍泛型(Generic Type)新技术——C#中的类型参数(Type Parameter)的方方面面,并解答c#泛型类的作用常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的''mapperHelper'' of bean class ... Does the parameter type of the setter match the return type of the getter?、Abstract Types && Parameterized Types、android – 类java.util.Map有泛型类型参数,请改用GenericTypeIndicator、c# – GetOriginalTypeParameterType throws未将对象引用设置为对象异常的实例

本文目录一览:

泛型(Generic Type)新技术——C#中的类型参数(Type Parameter)(c#泛型类的作用)

泛型(Generic Type)新技术——C#中的类型参数(Type Parameter)(c#泛型类的作用)

纠错

2021/9/16更正了本文中的概念错误:

泛型: Generic Type

类型参数: Type Parameter

简介

泛型Generic Type是编程中一个十分实用的技巧,很多语言(特别是面向对象语言)都提供了对泛型的支持。

随着时间的发展也不断地有针对泛型的新技术涌现出来,本文要给大家介绍的就是C#语言中针对泛型的新技术——类型参数Type Parameter

前提

学习本章之前,要对C#的类、接口、结构有所了解,不了解的同学推荐到这个网站先学习一下:菜鸟学院C#教程。

我使用的IDE是Visual Studio 2019 Community,使用的目标框架是.NET5.0。 安装教程

正文

首先看个示例:

using System;

Cls<string> clsStr = new(); // 完整版应该是Cls<string> clsStr = new Cls<string>(); 此处是简写。
clsStr.aoi = "clsStr中的类型参数TAoi被替换为了string类型";
Console.WriteLine(clsStr.aoi);

Cls<int> clsInt = new(); // clsInt中的类型参数TAoi被替换为了int类型。
clsInt.aoi = 38438;
Console.WriteLine(clsInt.aoi);


class Cls<TAoi> // 带有类型参数TAoi的类Cls
{
    internal TAoi aoi;
}

如上例所示,类型参数TAoi在类Cls中代表了一个尚未确定的数据类型;

创建实例clsStr时,为TAoi指定了实际类型string,所以clsStr中所有的TAoi类型都被替换为了string类型;

创建实例clsInt时,为TAoi指定了实际类型int,所以clsInt中所有的TAoi类型都被远的为了int类型。

还可以同时指定多个类型参数:

using System;

Cls<string, int> cls = new(); // C#区分大小写,所以Cls和cls并不冲突
cls.aoi = "clsStr中的类型参数TAoi被替换为了string类型";
cls.sola = 38438;
Console.WriteLine(cls.aoi);
Console.WriteLine(cls.sola);


class Cls<TAoi, TSola> // 带有两个类型参数的类Cls
{
    internal TAoi aoi;
    internal TSola sola;
}

类型参数还可应用于方法:

using System;

Cls cls = new();
cls.M<string, string>("TAoi aoi", "TSola sola"); // 调用时为类型参数指定实际类型
cls.M<int, int>(38438, 8384250); // 调用时为类型参数指定实际类型

class Cls
{
    internal void M<TAoi, TSola>(TAoi aoi, TSola sola) // 带有两个类型参数TAoi和TSola的方法M
    {
        Console.WriteLine(aoi);
        Console.WriteLine(sola);
    }
}

类型参数还可应用于接口:

using System;

InterFace<string, string> inter = new Cls();
inter.M1("aoi aoi aoi", "sola sola sola");
inter.M2<int, int>(38438, 8384250);



interface InterFace<TAoi, TSola>
{
    void M1(TAoi aoi, TSola sola);
    void M2<TMisaki, TRola>(TMisaki misaki, TRola rola); // 接口中的方法也可以带类型参数。
}

class Cls : InterFace<string, string> // 接口的类型参数在继承时就要指定实际类型
{
    void InterFace<string, string>.M1(string aoi, string sola) // 接口中方法M1的实现
    {
        Console.WriteLine(aoi);
        Console.WriteLine(sola);
    }


    // 接口中方法M2的实现;方法的类型参数要在调用时才能指定实际类型。
    void InterFace<string, string>.M2<TMisaki, TRola>(TMisaki misaki, TRola rola)
    {
        Console.WriteLine(misaki);
        Console.WriteLine(rola);
    }
}

类型参数还可应用于结构:

using System;

Struct<string, string> myStruct = new(); // 结构的类型参数在实例化时指定实际类型
myStruct.aoi = "aoi,aoi,aoi";
myStruct.sola = "sola,sola,sola";
myStruct.M<int, int>(38438, 8384250); // 方法的类型参数在调用时指定实际类型


struct Struct<TAoi, TSola> // 带类型参数TAoi和TSola的结构
{
    internal TAoi aoi;
    internal TSola sola;

    internal void M<TMisaki, TRola>(TMisaki misaki, TRola rola) // 带类型参数TMisaki和TRola的方法
    {
        Console.WriteLine(aoi);
        Console.WriteLine(sola);
        Console.WriteLine(misaki);
        Console.WriteLine(rola);
    }
}

''mapperHelper'' of bean class ... Does the parameter type of the setter match the return type of the getter?

''mapperHelper'' of bean class ... Does the parameter type of the setter match the return type of the getter?

Invalid property ''mapperHelper'' of bean class [org.mybatis.spring.mapper.MapperFactoryBean]: Bean property ''mapperHelper'' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

起因:多模块项目  以前没有这个问题 这个版本因为需求 新增了一个模块 然后再这个新增的模块下创建了许多子模块  然后再项目里扫描的地方配置了多路径  本地启服务正常 测试环境第一次通过 docker 启动也正常  但是后续通过脚本部署启动就报这个错 需要每次手动删除容器删除镜像手动运行命令启动才行 

网上查了 许多说是热部署插件的问题 但我们项目里压根就没有热部署 

MybatisConfiguration里的配置:
@MapperScans({@MapperScan("net.axx.bxx.*.mapper"),@MapperScan("net.axx.bxx.xxx.*.mapper")})
MapperScannerConfigurer里的配置:
mapperScannerConfigurer.setBasePackage("net.axx.bxx.*.mapper,net.axx.bxx.xxx.*.mapper");

 

大佬们 怎么解决呀

Abstract Types && Parameterized Types

Abstract Types && Parameterized Types

Abstract Types && Parameterized Types


Abstract Types(抽象类型) 

Scala 的抽象类型成员 (Abstract Type Members) 没有和 Java 等同的。 

两个语言中,类,接口 (Java), 特质 (Scala) 都可以有方法和字段作为成员。

Scala 的类 (class) 或特质 (trait) 可以有类型成员,下面例子是抽象类型成员:

object app_main extends App {
  // 通过给出这两个成员的具体定义来对这个类型进行实例化
  val abs = new AbsCell {
    override type T = Int
    override val init: T = 12
    override var me: S = "liyanxin"
  }

  println(abs.getMe)
  println(abs.getInit)

}

trait Cell {
  // 抽象类型成员S
  type S
  var me: S

  def getMe: S = me

  def setMe(x: S): Unit = {
    me = x
  }
}


/**
 * AbsCell 类既没有类型参数也没有值参数,
 * 而是定义了一个抽象类型成员 T 和一个抽象值成员 init。
 */
abstract class AbsCell extends Cell {

  //在子类内部具体化抽象类型成员S
  override type S = String
  // 抽象类型成员 T
  type T
  val init: T
  private var value: T = init

  def getInit: T = value

  def setInit(x: T): Unit = {
    value = x
  }
}

运行并输出:

liyanxin
0

参考:http://alanwu.iteye.com/blog/483959

https://github.com/wecite/papers/blob/master/An-Overview-of-the-Scala-Programming-Language/5.Abstraction.md

关于下面两者的区别:

abstract class Buffer {
  type T
  val element: T
}

rather that generics, for example,

abstract class Buffer[T{
  val element: T
}

请见:http://stackoverflow.com/questions/1154571/scala-abstract-types-vs-generics


Parameterized Types(参数化类型)

Scala supports parameterized types, which are very similar to generics in Java. (We could use the two terms interchangeably(可交换的), 

but it’s more common to use “parameterized types” in the Scala community and “generics” in the Java community.)  The most obvious difference is in the

syntax, where Scala uses square brackets ([...] ), while Java uses angle brackets (<...>).

用类型参数化类

For example, a list of strings would be declared as follows:

class GenCell[T](init: T) {
  private var value: T = init

  def get: T = value

  //Unit相当于返回void
  def set(x: T): Unit = {

    value = x
  }
}

在上面的定义中,“T” 是一个类型参数,可被用在 GenCell 类和它的子类中。类参数可以是任意 (arbitrary) 的名字。用 [] 来包围,而不是用 () 来包围,用以和值参数进行区别。


用类型参数化函数

如下代码示例

class GenCell[T](init: T) {
  private var value: T = init

  def get: T = value

  //Unit相当于返回void
  def set(x: T): Unit = {

    value = x
  }
}


object app_main extends App {

  //用T参数化函数
  def swap[T](x: GenCell[T], y: GenCell[T]): Unit = {
    val t = x.get;
    x.set(y.get);
    y.set(t)
  }

  val x: GenCell[Int] = new GenCell[Int](1)
  val y: GenCell[Int] = new GenCell[Int](2)
  swap[Int](x, y)

  println(x.get)
  println(y.get)
}

参考:https://github.com/wecite/papers/blob/master/An-Overview-of-the-Scala-Programming-Language/5.Abstraction.md

==============END==============

android – 类java.util.Map有泛型类型参数,请改用GenericTypeIndicator

android – 类java.util.Map有泛型类型参数,请改用GenericTypeIndicator

我正在使用firebase从数据库中检索数据

Map< String,String> map = dataSnapshot.getValue(Map.class);

获取值,但它显示错误

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                 Process: com.rana.sahaj.myyu, PID: 13179
                                                                 com.google.firebase.database.DatabaseException: Class java.util.Map has generic type parameters, please use GenericTypeIndicator instead
                                                                     at com.google.android.gms.internal.zzaix.zzb(UnkNown Source)
                                                                     at com.google.android.gms.internal.zzaix.zza(UnkNown Source)
                                                                     at com.google.firebase.database.DataSnapshot.getValue(UnkNown Source)
                                                                     at com.rana.sahaj.myyu.profile.Profile$2.onDataChange(Profile.java:158)
                                                                     at com.google.android.gms.internal.zzafp.zza(UnkNown Source)
                                                                     at com.google.android.gms.internal.zzagp.zzSu(UnkNown Source)
                                                                     at com.google.android.gms.internal.zzags$1.run(UnkNown Source)
                                                                     at android.os.Handler.handleCallback(Handler.java:733)
                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                     at android.os.Looper.loop(Looper.java:136)
                                                                     at android.app.ActivityThread.main(ActivityThread.java:5052)
                                                                     at java.lang.reflect.Method.invokeNative(Native Method)
                                                                     at java.lang.reflect.Method.invoke(Method.java:515)
                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
                                                                     at dalvik.system.NativeStart.main(Native Method)

这是代码

 DatabaseReference profileRef=mFirebaseRef.child(EEmail);
    profileRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

    -->     Map<String, String> map = (Map<String,String>)dataSnapshot.getValue(Map.class);

            name = (TextView)findViewById(R.id.UserInActivity);
            EmailView= (TextView)findViewById(R.id.emailUser);

            PhotoUrl = map.get("picurl");
             emmaill=map.get("userEmail");

            UserNam = map.get("userNAME");

            name.setText(UserNam);
            EmailView.setText(emmaill);


        }

        @Override
        public void onCancelled(DatabaseError firebaseError) {

        }
    });

n数据库中的键n值没有问题.
使用了解决方案,但没有工作

解决方法:

错误指出您出错的地方

 Map<String, String> map = dataSnapshot.getValue(Map.class);

Map类使用参数来定义Key和Object的类型,而不提供它们,只需使用失败的Map.class.

尝试下面的代码 – 因为Key总是字符串,我们可以为它们提供任何类型的Object

    Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();

c# – GetOriginalTypeParameterType throws未将对象引用设置为对象异常的实例

c# – GetOriginalTypeParameterType throws未将对象引用设置为对象异常的实例

参考: How can a dynamic be used as a generic?
public void CheckEntity(int entityId,string entityType = null)
{
 dynamic AnyObject = Activator.CreateInstance("Assembly","Assembly.Models.DbModels." + entityType).Unwrap();
 CheckWithInference(AnyObject,entityId);
}

private static void CheckWithInference<T>(T ignored,int entityId) where T : class
{
 Check<T>(entityId);
}

private static void Check<T>(int entityId) where T : class
{
 using (var gr = new GenericRepository<T>())
 {
 }
}

这与CheckEntity(16,“容器”)进入;第一行运行后,AnyObject在使用调试器检查时变为空白Assembly.Models.DbModels.Container.如果var AnyType = AnyObject.GetType();使用,然后AnyType显示为Assembly.Models.DbModels.Container.但是,当调用CheckWithInference(AnyObject,entityId)时;被抛出异常.

> outer:对象引用未设置为对象的实例.
> inner:Microsoft.CSharp.RuntimeBinder.SymbolTable.GetoriginalTypeParameterType(Type t)10

我在这里做了一个自包含的例子 – 但它运行没有错误:(

注意,这是在asp.net mvc 3 c#

HomeController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace InferenceExample.Controllers
{
public class HomeController : Controller
{
    //
    // GET: /Home/

    public ActionResult Index()
    {
        return View();
    }

    public void CheckEntity(int entityId,string entityType = null)
    {
        dynamic AnyObject = Activator.CreateInstance("InferenceExample","InferenceExample.Models." + entityType).Unwrap();
        CheckWithInference(AnyObject,entityId);
    }

    private static void CheckWithInference<T>(T ignored,int entityId) where T : class
    {
        Check<T>(entityId);
    }

    private static void Check<T>(int entityId) where T : class
    {
        var repo = new List<T>();
    }

}
}

Example.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace InferenceExample.Models
{
public class Example
{
    public int ExampleId { get; set; }
    public string Name { get; set; }
}
}

Index.cshtml

@{
ViewBag.Title = "Index";
}

<h2>Index</h2>

@Html.ActionLink("Start","CheckEntity",new { entityId = 16,entityType = "Example" })

我很茫然.为什么会得到这个例外?我无法轻易复制它.我不确定该示例还包含哪些内容,因为这是实际代码中的所有内容.

真正令人困惑的部分是在应用程序中,当发生此异常时,操作失败.但是,在重新访问页面并再次尝试时,不会抛出任何异常.

解决方法

正如在C#聊天室中所讨论的,这里的解决方案是完全绕过动态并使用反射来调用泛型方法. Dynamic有一些很好的功能,但有时会造成比它值得更多的麻烦,特别是当它可以在运行时获取Type对象时.
var modelType = Type.GetType("InferenceExample.Models." + entityType + ",InferenceExample");

var checkMethod = typeof(HomeController).getmethod("CheckWithInference",BindingFlags.NonPublic | BindingFlags.Static);
checkMethod.MakeGenericmethod(modelType).Invoke(null,new object[] { entityId });

乐意效劳 :)

今天关于泛型(Generic Type)新技术——C#中的类型参数(Type Parameter)c#泛型类的作用的介绍到此结束,谢谢您的阅读,有关''mapperHelper'' of bean class ... Does the parameter type of the setter match the return type of the getter?、Abstract Types && Parameterized Types、android – 类java.util.Map有泛型类型参数,请改用GenericTypeIndicator、c# – GetOriginalTypeParameterType throws未将对象引用设置为对象异常的实例等更多相关知识的信息可以在本站进行查询。

本文标签: