繁体   English   中英

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

[英]Convert C# generic method to objective-C

很长的故事:

我的一位同事向我求了一点帮助。 我是一名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 equilivant的方法?


更新1

我们错误的实施基于尼古拉斯凯里的想法。


- (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;
}

在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类方法( static方法,在C#范围内)。 这样,您可以只将类传递给工厂方法,并且工厂方法可以在类中查询正确的标识符。

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

- (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 ++)需要泛型。 没有它们,问题就不会[很容易]知道它对所包含的对象能做什么或不能做什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM