将c#泛型方法转换为objective-C

本文关键字:objective-C 转换 泛型方法 | 更新日期: 2023-09-27 18:14:57

说来话长:

我的一个同事向我寻求一点帮助。我是c#开发人员,他是iOS开发人员,阅读彼此的代码有时会让我们有一些很好的见解。

他正在编写一个函数,该函数需要返回一个基类型为UITableViewCell的对象,并以整数作为输入。实际的返回类型是UITableViewCell的一个子类。他问我是否有一个更好的解决方案,而不是一个简单的开关,像这样:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (row) {
        case 0: {
            NSString *CellIdentifier = @"personCell";
            PersonInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                cell = [[PersonInfoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            }
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            return cell;
            break;
        }
        case 1: {
            NSString *CellIdentifier = @"photoCell";
            PhotoCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                cell = [[PhotoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            }
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            return cell;
            break;
        }
        default:
            return nil; //Don't care about this atm. Not the problem.
            break;
    }
}

我的c#实现是这样的:

public UITableViewCell TableViewCellForRowAtIndexPath(UITableView tableView, NSIndexPath indexPath)
{
    switch(indexPath.row)
    {
        case 0:
        return MakeCell<PersonInfoCell>();
        case 1:
            return MakeCell<PhotoCell>();
        default:
            return null; //Still doesn't matter
    }
}

public TCell MakeCell<TCell>() where TCell : UITableViewCell, new()
{
    TCell cell = new TCell();
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}
public class PersonInfoCell : UITableViewCell
{
    //Dont care about implementation yet....
    //TL;DR
}
public class PhotoCell : UITableViewCell
{
    //Dont care about implementation yet....
    //TL;DR
}

短篇小说:

有谁知道一种方法来转换我的c#通用代码到objective-c平衡?


<标题>更新1

我们错误的实现基于Nicholas Carey的想法。

<>之前 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { switch (row) { case 0: { NSString *CellIdentifier = @"personCell"; PersonInfoCell *cell = (PersonInfoCell *)[self makeCell:CellIdentifier]; //Do PersonInfoCell specific stuff with cell return cell; break; } case 1: { NSString *CellIdentifier = @"photoCell"; PhotoCell *cell = (PhotoCell *)[self makeCell:CellIdentifier]; //Do PhotoCell specific stuff with cell return cell; break; } default: return nil; //Don't care about this atm. Not the problem. break; } } - (id *)makeCell:(NSString *)cellIdentifier { id cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { cell = [[PhotoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; // <---- how does this method know it is a PhotoCell I want? //PhotoCell??? } cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; }

将c#泛型方法转换为objective-C

在Objective-C中,类是第一类结构,可以像其他对象一样传递和使用。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = nil;
    Class cellClass = nil;
    switch (row) {
        case 0:
            cellIdentifier = @"personCell";
            cellClass = [PersonInfoCell class];
            break;
        case 1:
            cellIdentifier = @"photoCell";
            cellClass = [PhotoCell class];
            break;
        default:
            return nil; //Don't care about this atm. Not the problem.
    }
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
        cell = [[cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

如果你真的想把工厂方法提出来,你可以这样做:

- (UITableViewCell *)getOrCreateCellForTable:(UITableView *)tableView withIdentifier:(NSString *)cellIdentifier class:(Class)cellClass
{
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
  if (cell == nil)
      cell = [[cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
  cell.selectionStyle = UITableViewCellSelectionStyleNone;
  return cell;
}

如果您想摆脱成对的cellIdentifiercellClass参数,一个选项是在您使用的每个单元格类上创建defaultIdentifier类方法(用c#的说法是static方法)。这样,您就可以只将类传递给工厂方法,而工厂方法可以查询类以获得正确的标识符。

基于David Mitchell的代码,我们(synnercoder的同事)想出了这个,工作完美!

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = nil;
    Class cellClass = nil;
    switch (indexPath.row) {
        case 0: {
            cellIdentifier = @"personCell";
            cellClass = [PersonInfoCell class];
            PersonInfoCell *personInfoCell = (PersonInfoCell *)[self getOrCreateCellForTable:tableView withIdentifier:cellIdentifier class:cellClass];
            personInfoCell.delegate = self;
            return personInfoCell;
        }
        case 1: {
            cellIdentifier = @"photoCell";
            cellClass = [LastMeasureMent class];
            LastMeasureMent *measurementCell = (LastMeasureMent *)[self getOrCreateCellForTable:tableView withIdentifier:cellIdentifier class:cellClass];
            measurementCell.selectionStyle = UITableViewCellSelectionStyleBlue;
            return measurementCell;
        }
        default: {
            cellIdentifier = @"photoCell";
            cellClass = [LastMeasureMent class];
            LastMeasureMent *measurementCell = (LastMeasureMent *)[self getOrCreateCellForTable:tableView withIdentifier:cellIdentifier class:cellClass];
            measurementCell.selectionStyle = UITableViewCellSelectionStyleBlue;
            return measurementCell;
        }
    }

}
- (UITableViewCell *)getOrCreateCellForTable:(UITableView *)tableView withIdentifier:(NSString *)cellIdentifier class:(Class)cellClass
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
        cell = [[cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

谢谢大卫!

看这个问题:Objective-C中有强类型集合吗?

Objective-C是后绑定和动态类型的,所以你不需要泛型。您可以向对象发送任何消息。它用它做什么取决于对象。具有静态类型的早期绑定语言(如c#、Java、c++)需要泛型。如果没有它们,问题就不会[容易]知道它对所包含的对象能做什么或不能做什么。