C# 返回Id的常规函数
在我的项目中,我编写了自己的地图绘制程序,在很多地方我都在做类似的事情C# 返回Id的常规函数,c#,C#,在我的项目中,我编写了自己的地图绘制程序,在很多地方我都在做类似的事情 tbl.Type!=无效的tbl.Type.Id:0返回引用对象的Id。 因为这种情况发生了很多次,所以我试着做一个小函数来为我做这个检查,不管我传递的对象是什么类型的 我当时在想 public static int returnId(object input) { if(input != null && input.Id != null) { return input.Id;
tbl.Type!=无效的tbl.Type.Id:0
返回引用对象的Id。
因为这种情况发生了很多次,所以我试着做一个小函数来为我做这个检查,不管我传递的对象是什么类型的
我当时在想
public static int returnId(object input)
{
if(input != null && input.Id != null)
{
return input.Id;
}
return 0;
}
或者可能使用泛型类型
当前,此函数引发错误,因为对象
不包含.Id
的定义。我已经在谷歌上搜索了几个小时,开始怀疑我要找的东西是否可能
欢迎您的任何帮助和想法,我们将不胜感激 所有输入应实现IId
接口:
public static int returnId(IId input)
{
if(input != null && input.Id != null)
{
return input.Id;
}
return 0;
}
或通过反射:
public static int returnId(object input)
{
if(input != null)
{
var Id = input.GetType().GetProperty("Id").GetValue(input);
if(Id != null)
return ((int?)Id).Value;
}
return 0;
}
您有两个选择:
1:使用动态
而不是对象
:
public static int returnId(dynamic input)
{
if(input != null && input.Id != null)
{
return input.Id;
}
return 0;
}
2:让您的所有类从定义id
的接口继承:
public static int returnId(IId input)
{
if(input != null && input.Id != null)
{
return input.Id;
}
return 0;
}
public interface IId
{
int Id {get; set;}
}
第二个选项应该具有更好的性能,因为需要在运行时解析操作。您可以使用继承并为每个类实现
Id
属性。大概是这样的:
public abstract class ObjectId
{
// Or as auto-propert `public virtual int Id { get; private set; }`.
public abstract int Id { get; }
}
public class ObjectImpl : ObjectId
{
public override int Id
{
get { return 0; }
}
}
除了此实现之外,还可以为基类定义默认值(作为虚拟属性)。因此,并非每个类都必须重写属性Id
使用此实现,您可以将ObjectId
作为输入类型传递给函数,如果null
则返回0
public static int returnId(ObjectId input)
{
return (input != null) ? input.Id : 0; // input.Id will never be null.
}
你想做的事在一般情况下是不可行的。如果希望能够检索对象的Id,则需要确保在方法中使用的每个类型中都存在属性Id 在大多数情况下,最好的选择是遵循斯拉瓦最初的建议,即(稍加改进)
公共接口IId
{
int Id{get;}
}
公共静态int returnId(T输入),其中T:IId
{
返回输入!=null?输入。Id:0;
}
使用动态和反射(例如input.GetType().GetProperty(“Id”).GetValue(input))会产生类似的效果,但是
1) 它不提供编译时保证-所有验证都在运行时完成,如果类型没有名为“Id”的属性,则验证将失败;
2) 运行时逻辑对性能有负面影响,这在高强度使用期间是显而易见的
正如@hofmeister所建议的,只有当您只需要将此方法应用于您自己定义的类型,而不是任何第三方类时,继承才是一个选项。是否
object
始终是自定义类型?object
将是我在C#6中定义的类,您可以使用tbl.type?.Id??0
我真希望我早知道这一点。是一件事。这样我就省去了很多麻烦。我会用的,谢谢!那里不需要泛型。不错,人们通常看不到接口的需要,当它盯着它们看时,为什么Id
应该是抽象的?@nozzleman我对派生类一无所知。对于抽象属性,每个类都有自己的实现。是的,我明白了,我假设每个类都可能会使用自动属性来实现它,因此将其设置为虚拟自动属性仍然允许在极少数情况下重写它,需要另一个实现。只有抽象属性的抽象类
基本上是一个接口
。除此之外,如果OP选择让所有必需的类实现抽象类,那么抽象类是有意义的;)@确实是nozzleman,但我也提到了默认实现(auto属性)。没有关于对象的任何细节,我们只能猜测最佳实现。
public interface IId
{
int Id {get;}
}
public static int returnId<T>(T input) where T : IId
{
return input != null ? input.Id : 0;
}