类映射错误:“T"必须是具有公共无参数构造函数的非抽象类型 [英] Class Mapping Error: 'T' must be a non-abstract type with a public parameterless constructor
问题描述
在映射类时,我收到错误T"必须是具有公共无参数构造函数的非抽象类型,以便将其用作泛型类型或方法中的参数T".
While mapping class i am getting error 'T' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method.
下面是我的 SqlReaderBase 类
Below is my SqlReaderBase Class
public abstract class SqlReaderBase<T> : ConnectionProvider
{
#region Abstract Methods
protected abstract string commandText { get; }
protected abstract CommandType commandType { get; }
protected abstract Collection<IDataParameter> GetParameters(IDbCommand command);
**protected abstract MapperBase<T> GetMapper();**
#endregion
#region Non Abstract Methods
/// <summary>
/// Method to Execute Select Queries for Retrieveing List of Result
/// </summary>
/// <returns></returns>
public Collection<T> ExecuteReader()
{
//Collection of Type on which Template is applied
Collection<T> collection = new Collection<T>();
// initializing connection
using (IDbConnection connection = GetConnection())
{
try
{
// creates command for sql operations
IDbCommand command = connection.CreateCommand();
// assign connection to command
command.Connection = connection;
// assign query
command.CommandText = commandText;
//state what type of query is used, text, table or Sp
command.CommandType = commandType;
// retrieves parameter from IDataParameter Collection and assigns it to command object
foreach (IDataParameter param in GetParameters(command))
command.Parameters.Add(param);
// Establishes connection with database server
connection.Open();
// Since it is designed for executing Select statements that will return a list of results
// so we will call command's execute reader method that return a Forward Only reader with
// list of results inside.
using (IDataReader reader = command.ExecuteReader())
{
try
{
// Call to Mapper Class of the template to map the data to its
// respective fields
MapperBase<T> mapper = GetMapper();
collection = mapper.MapAll(reader);
}
catch (Exception ex) // catch exception
{
throw ex; // log errr
}
finally
{
reader.Close();
reader.Dispose();
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
connection.Close();
connection.Dispose();
}
}
return collection;
}
#endregion
}
我想做的是,我正在执行一些命令并动态填充我的课程.课程如下:
What I am trying to do is , I am executine some command and filling my class dynamically. The class is given below:
namespace FooZo.Core
{
public class Restaurant
{
#region Private Member Variables
private int _restaurantId = 0;
private string _email = string.Empty;
private string _website = string.Empty;
private string _name = string.Empty;
private string _address = string.Empty;
private string _phone = string.Empty;
private bool _hasMenu = false;
private string _menuImagePath = string.Empty;
private int _cuisine = 0;
private bool _hasBar = false;
private bool _hasHomeDelivery = false;
private bool _hasDineIn = false;
private int _type = 0;
private string _restaurantImagePath = string.Empty;
private string _serviceAvailableTill = string.Empty;
private string _serviceAvailableFrom = string.Empty;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Address
{
get { return _address; }
set { _address = value; }
}
public int RestaurantId
{
get { return _restaurantId; }
set { _restaurantId = value; }
}
public string Website
{
get { return _website; }
set { _website = value; }
}
public string Email
{
get { return _email; }
set { _email = value; }
}
public string Phone
{
get { return _phone; }
set { _phone = value; }
}
public bool HasMenu
{
get { return _hasMenu; }
set { _hasMenu = value; }
}
public string MenuImagePath
{
get { return _menuImagePath; }
set { _menuImagePath = value; }
}
public string RestaurantImagePath
{
get { return _restaurantImagePath; }
set { _restaurantImagePath = value; }
}
public int Type
{
get { return _type; }
set { _type = value; }
}
public int Cuisine
{
get { return _cuisine; }
set { _cuisine = value; }
}
public bool HasBar
{
get { return _hasBar; }
set { _hasBar = value; }
}
public bool HasHomeDelivery
{
get { return _hasHomeDelivery; }
set { _hasHomeDelivery = value; }
}
public bool HasDineIn
{
get { return _hasDineIn; }
set { _hasDineIn = value; }
}
public string ServiceAvailableFrom
{
get { return _serviceAvailableFrom; }
set { _serviceAvailableFrom = value; }
}
public string ServiceAvailableTill
{
get { return _serviceAvailableTill; }
set { _serviceAvailableTill = value; }
}
#endregion
public Restaurant() { }
}
}
为了动态填充我的类属性,我有另一个名为 MapperBase Class 的类,其中包含以下方法:
For filling my class properties dynamically i have another class called MapperBase Class with following methods:
public abstract class MapperBase<T> where T : new()
{
protected T Map(IDataRecord record)
{
T instance = new T();
string fieldName;
PropertyInfo[] properties = typeof(T).GetProperties();
for (int i = 0; i < record.FieldCount; i++)
{
fieldName = record.GetName(i);
foreach (PropertyInfo property in properties)
{
if (property.Name == fieldName)
{
property.SetValue(instance, record[i], null);
}
}
}
return instance;
}
public Collection<T> MapAll(IDataReader reader)
{
Collection<T> collection = new Collection<T>();
while (reader.Read())
{
collection.Add(Map(reader));
}
return collection;
}
}
还有另一个类继承了 SqlreaderBaseClass,称为 DefaultSearch.代码如下
There is another class which inherits the SqlreaderBaseClass called DefaultSearch. Code is below
public class DefaultSearch: SqlReaderBase<Restaurant>
{
protected override string commandText
{
get { return "Select Name from vw_Restaurants"; }
}
protected override CommandType commandType
{
get { return CommandType.Text; }
}
protected override Collection<IDataParameter> GetParameters(IDbCommand command)
{
Collection<IDataParameter> parameters = new Collection<IDataParameter>();
parameters.Clear();
return parameters;
}
protected override MapperBase<Restaurant> GetMapper()
{
MapperBase<Restaurant> mapper = new RMapper();
return mapper;
}
}
但是每当我尝试构建时,我都会收到错误T"必须是具有公共无参数构造函数的非抽象类型,以便将其用作泛型类型或方法中的参数T".即使 T 这里是 Restaurant 也有一个无参数公共构造函数.
But whenever I tried to build , I am getting error 'T' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method. Even T here is Restaurant has a Parameterless Public constructor.
推荐答案
问题是您试图使用 SqlReaderBase
中的 T
作为类型参数MapperBase
- 但你对那个 T
没有任何限制.
The problem is that you're trying to use the T
from SqlReaderBase
as the type argument for MapperBase
- but you don't have any constraints on that T
.
尝试将您的 SqlReaderBase
声明更改为:
Try changing your SqlReaderBase
declaration to this:
public abstract class SqlReaderBase<T> : ConnectionProvider
where T : new()
这是一个更简短的示例,它演示了相同的问题:
Here's a shorter example which demonstrates the same issue:
class Foo<T>
{
Bar<T> bar;
}
class Bar<T> where T : new()
{
}
修复方法是将 Foo
的声明更改为:
The fix is to change Foo<T>
's declaration to:
class Foo<T> where T : new()
然后编译器就会知道 Foo
中的 T
是 Bar
的有效类型参数.
Then the compiler will know that the T
from Foo
is a valid type argument for Bar
.
这篇关于类映射错误:“T"必须是具有公共无参数构造函数的非抽象类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!