在我的项目中,我已经编写了自己的地图制作者,并且在很多地方我都在做类似的事情。
public static int returnId(object input)
{
if(input != null && input.Id != null)
{
return input.Id;
}
return 0;
}
返回引用对象的id。
因为这种情况已经发生了很多次,所以无论我传递的物体类型如何,我都试图制作一个能够对我进行检查的小功能。
我正在思考
<T>
或者可能使用通用类型object
。
目前此函数会引发错误,因为.Id
不包含SortedList
的定义。我现在正在谷歌上搜索几个小时,并开始怀疑我能找到的是否可能。
欢迎任何帮助和想法,非常感谢!
答案 0 :(得分:1)
所有输入应实现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 :(得分:1)
您有两种选择:
1:使用dynamic
代替object
:
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;}
}
第二个选项应该有更好的性能,因为dynamic要求在运行时解析操作。
答案 2 :(得分:1)
在一般情况下,您尝试做的事情是不可行的。如果您希望能够检索对象的ID,则需要确保您在方法中使用的每种类型都存在属性ID。
在大多数情况下,最好的选择是遵循Slava的原始建议,即(略有改进)
public interface IId
{
int Id {get;}
}
public static int returnId<T>(T input) where T : IId
{
return input != null ? input.Id : 0;
}
使用动态和反射(例如input.GetType()。GetProperty(&#34; Id&#34;)。GetValue(输入))会产生类似的效果,但是 1)它不提供编译时保证 - 所有验证都在运行时完成,如果类型没有名为&#34; Id&#34 ;; 2)运行时逻辑对性能有负面影响,这在强烈使用期间是可见的。
只有在您只需要将此方法应用于您自己定义的类型而不是任何第三方类时,@ bomeister建议的继承是一种选择。
答案 3 :(得分:0)
您可以使用继承并为每个类实现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
作为输入类型传递给您的函数,如果它是0
则返回null
。
public static int returnId(ObjectId input)
{
return (input != null) ? input.Id : 0; // input.Id will never be null.
}