我有两个具有两个公共属性Id
和SortNumber
的类。我想有一个通用的方法来对所述类列表中的项目进行排序。
是否可以不实现类IOrderitem
和Foo
的接口Bar
,但仍然可以使用方法MoveUp
?
还是reflection是唯一的选择?过去几年来一直在编写TypeScript代码,因此对C#有点生锈。
public class Foo
{
public int Id {get;set;}
public int SortNumber {get;set;}
// etc
}
public class Bar
{
public int Id {get;set;}
public int SortNumber {get;set;}
// etc
}
public interface IOrderitem
{
int Id {get;set;}
int SortNumber {get;set;}
}
public static void MoveUp<T>(List<T> itemList, int id)
{
for (int i = 0; i < itemList.Count; i++)
{
// reindex items
var item = itemList[i] as IOrderItem;
bool isItem = item.Id == id;
if (isItem && i > 0)
{
// set item above eventinfo item to one position lower (0 = top rest lower)
(itemList[i - 1] as IOrderItem).SortNumber = i;
// set the item to move up one position higher (0 = top rest lower)
item.SortNumber = i - 1;
i++;
}
else
{
item.SortNumber = i;
}
}
}
答案 0 :(得分:0)
您可以为Foo和Bar实现一个基类,并从其继承。
public class BaseClass
{
public int Id { get; set; }
public int SortNumber { get; set; }
// etc
}
class Foo : BaseClass { }
class Bar : BaseClass { }
您可以使用动态方法来代替创建具有已定义类型的T列表。但是我不建议这样做。不推荐。请参阅链接Is the use of dynamic considered a bad practice?
public static void MoveUp(List<dynamic> itemList, int id)
{
// ....
}
然后您可以照常使用“属性”,但是以后重命名都可能导致崩溃。
实际上,所有取决于您的目的是不使用接口,这对我来说并不明确。
答案 1 :(得分:0)
您在评论中写道:
我想知道是否可以在没有接口-或-基类-或-抽象类的情况下完成。我正在使用不希望更改的通用项目中存在的EF类。
因此,您需要使用鸭子打字功能。
C#是一种强类型语言。鸭子打字是一种动态语言功能。尽管有duck typing in the C# compiler itself的一些示例(例如,参见foreach
或await
),但是鸭子类型的广泛使用打破了强类型语言的目的:编译时类型安全。
有两种方法可以在C#中实现它:使用Reflection或dynamic
。两者都很慢。
我可以向您展示dynamic
的方法。
在您的MoveUp<T>
方法中,使用
var item = itemList[i] as dynamic;
代替
var item = itemList[i] as IOrderItem;
所以现在T
甚至可以是typeof(object)
。您可以访问Id
和SortNumber
属性-它们仅需要存在于该对象上。 但是:这有点放弃了使用泛型获得的所有好处。
缺点:
我为您创建了一个简单的基准。我有一个List<Item>
,带有10.000个对象。我这样做:
for (int i = 0; i < 10_000; i++)
{
sum += objects[i].Value;
}
和
for (int i = 0; i < 10_000; i++)
{
dynamic o = objects[i] as dynamic;
sum += o.Value;
}
结果是:
| Method | Mean | Error | StdDev |
|----------- |----------:|----------:|----------:|
| Direct | 11.22 us | 0.0268 us | 0.0251 us |
| Dynamic | 256.15 us | 0.9606 us | 0.8986 us |
因此dynamic
方法的速度要慢23倍(在我的机器上,使用.NET Framework 4.7.2(CLR 4.0.30319.42000),64位RyuJIT-v4.7.3324.0)。