虽然映射类我得到错误'T'必须是具有公共无参数构造函数的非抽象类型,以便在泛型类型或方法中将其用作参数'T'.
下面是我的SqlReaderBase类
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
}
Run Code Online (Sandbox Code Playgroud)
我要做的是,我执行一些命令并动态填充我的类.课程如下:
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() { }
}
}
Run Code Online (Sandbox Code Playgroud)
为了动态填充我的类属性,我有另一个名为MapperBase Class的类,其中包含以下方法:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
还有另一个类继承了名为DefaultSearch的SqlreaderBaseClass.代码如下
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;
}
}
Run Code Online (Sandbox Code Playgroud)
但每当我尝试构建时,我都会收到错误'T'必须是带有公共无参数构造函数的非抽象类型,以便在泛型类型或方法中将其用作参数'T'.甚至T这里是Restaurant有一个Parameterless Public构造函数.
Jon*_*eet 117
问题是,你试图使用T从SqlReaderBase作为类型参数MapperBase-但你没有任何的约束是 T.
尝试将您的SqlReaderBase声明更改为:
public abstract class SqlReaderBase<T> : ConnectionProvider
where T : new()
Run Code Online (Sandbox Code Playgroud)
这是一个更短的例子,它展示了同样的问题:
class Foo<T>
{
Bar<T> bar;
}
class Bar<T> where T : new()
{
}
Run Code Online (Sandbox Code Playgroud)
解决方法是将Foo<T>声明更改为:
class Foo<T> where T : new()
Run Code Online (Sandbox Code Playgroud)
然后编译器将知道Tfrom Foo是一个有效的类型参数Bar.
Mar*_*ell 12
约束必须适用于链中的每个类型; 因此你需要:
public abstract class SqlReaderBase<T> : ConnectionProvider where T : new()
Run Code Online (Sandbox Code Playgroud)
如果没有这个,你就无法满足Tin中的约束:
protected abstract MapperBase<T> GetMapper();
Run Code Online (Sandbox Code Playgroud)
要么
MapperBase<T> mapper = GetMapper();
Run Code Online (Sandbox Code Playgroud)
因为MapperBase<>是仅当可用T具有: new()
我遇到过同样的问题。我应该在谷歌搜索之前阅读该消息。我需要添加一个无参数构造函数...:-)
public MyClass() {
//stuff
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
52919 次 |
| 最近记录: |