Обновление 4:
Я нашел, как исправить другую ошибку:
interface IRule<TEntity>
where TEntity : TableEntity, new()
Но тогда у меня возникает проблема с добавлением моего AddressRule в правила в классе Validator.
public Validator()
{
Rules = new List<IRule<TableEntity>>();
var addressRule = new AddressRule();
Rules.Add(addressRule);
}
Обновление 3:
Теперь я обновил код ниже:
interface IRule<TEntity> where TEntity : TableEntity
{
string TableName { get; }
string Rule { get; }
string SaveToTable { get; }
ReportEntity Handle(TableEntity entity);
TableQuery<TEntity> GetTableQuery();
}
Что я указал, какой тип класса должен быть TEntity, он удаляет 1-ю ошибку, но 2-я ошибка сохраняется:
Ошибка CS0310 «TEntity» должен быть неабстрактным типом с общедоступным конструктором без параметров, чтобы использовать его в качестве параметра «TElement» в универсальном типе или методе «TableQuery».
Обновление 2:
После применения предложения Juston.Another.Programmer я получил эту ошибку.
Обновлять:
Я использую шаблон стратегии, у меня есть куча правил, и мне нужно проверить все строки в таблице хранилища Azure по каждому правилу.
interface IRule where TEntity : TableEntity, new()
{
string TableName { get; } // It could be "ContractAccount", "Bill", "Transaction" etc.
string Rule { get; }
string SaveToTable { get; }
TableQuery<TEntity> TableQuery { get; }
ReportEntity Handle(TableEntity entity);
}
Итак, экземпляр правил живет внутри валидатора.
public Validator()
{
Rules = new List<IRule>();
Rules.Add(new AddressRule());
}
Класс Table Entity (ContractAccount.cs Bill.cs и т. д.) будет иметь то же имя, что и значение IRule.TableName.
Так вот откуда взялся ContractAccount.
Затем в валидаторе у меня есть Validate(), который выглядит так:
public async void Validate(CloudStorageAccount storageAccount)
{
var tableClient = storageAccount.CreateCloudTableClient();
//.....
var query = new TableQuery<ContractAccount>(); //<-- I want to replace ContractAccount with something generic
//...
var rows = await tableToBeValidated.ExecuteQuerySegmentedAsync(query, token);
}
//...
}
В моем AddressRule.cs
public class AddressRule : IRule<ContractAccount>
{
public string TableName => "ContractAccount";
public string Rule => "Email cannot be empty";
public string SaveToTable => "XXXX";
public TableQuery<ContractAccount> TableQuery => new TableQuery<ContractAccount>();
public ReportEntity Handle(TableEntity entity)
{
var contract = entity as ContractAccount;
if(contract == null)
{
throw new Exception($"Expecting entity type {TableName}, but passed in invalid entity");
}
if (string.IsNullOrWhiteSpace(contract.Address))
{
var report = new ReportEntity(this.Rule, contract.UserId, contract.AccountNumber, contract.ContractNumber)
{
PartitionKey = contract.UserId,
RowKey = contract.AccountNumber
};
return report;
}
return null;
}
}
Как вы видете
var query = new TableQuery<ContractAccount>();
Мне нужно заменить Hard-coded на что-то вроде:
var type = Type.GetType(tableName);
var query = new TableQuery<type>();
но заполнитель (ContractAccount) будет меняться при запуске приложения, это может быть счет, политика, транзакция и т. д....
я не могу использовать
<T>
предмет.
Как я могу заменить ContractAccount чем-то общим?
Спасибо
T
в любой метод, в котором находится этот код? - person Sweeper   schedule 26.06.2019