简体   繁体   English

返回ID的一般功能

[英]General function to return Id

In my project i've written my own mappers, and there's a lot of places where I'm doing things like tbl.Type != null ? tbl.Type.Id : 0 在我的项目中,我编写了自己的映射器,在很多地方我都在做类似tbl.Type != null ? tbl.Type.Id : 0事情tbl.Type != null ? tbl.Type.Id : 0 tbl.Type != null ? tbl.Type.Id : 0 to return the id of referenced objects. tbl.Type != null ? tbl.Type.Id : 0返回引用对象的ID。 Because this is occuring so many times, I'm trying to make a small function that does this check for me, no matter the type of object I pass. 由于这种情况发生了很多次,因此无论我传递的对象类型如何,我都试图创建一个小的函数来为我执行此检查。

I was thinking along the lines of 我一直在思考

public static int returnId(object input)
{
    if(input != null && input.Id != null)
    {
        return input.Id;
    }
    return 0;
}

or maybe using generic type <T> . 或使用通用类型<T>

Currently this function throws errors because object doesn't contain a definition for .Id . 当前,此函数引发错误,因为object不包含.Id的定义。 I've been googling around for a few hours now, and start to wonder if what I'm looking for is even possible. 我已经搜寻了几个小时,开始怀疑我在寻找什么甚至可能。

Any help and ideas are welcome and much appreciated! 欢迎任何帮助和想法,并深表感谢!

All inputs should implement IId interface: 所有输入都应实现IId接口:

public static int returnId(IId input)
{
    if(input != null && input.Id != null)
    {
        return input.Id;
    }
    return 0;
}

Or via reflection: 或通过反射:

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

You have two options: 您有两种选择:

1: Use dynamic instead of object : 1:使用dynamic代替object

public static int returnId(dynamic input)
{
    if(input != null && input.Id != null)
    {
        return input.Id;
    }
    return 0;
}

2: Have all your classes inherit from an interface that defines id : 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;}
}

The 2nd option should have better performance, because dynamic requires the operation to be resolved at runtime. 第二个选项应该具有更好的性能,因为动态要求在运行时解析操作。

What you're trying to do is not feasible in the general case. 在一般情况下,您尝试执行的操作不可行。 If you want to be able to retrieve an object's Id you need to ensure that property Id exists in every type you would use with your method. 如果希望能够检索对象的ID,则需要确保在将与方法一起使用的每种类型中都存在属性ID。

In most cases the best option would be to follow Slava's original suggestion, namely (with minor enhancements) 在大多数情况下,最好的选择是遵循Slava的原始建议,即(稍作增强)

public interface IId
{
    int Id {get;}
}

public static int returnId<T>(T input) where T : IId
{
    return input != null ? input.Id : 0;
}

Using dynamic and reflection (eg input.GetType().GetProperty("Id").GetValue(input)) would have a similar effect, but 1) it provides no compile-time guarantees - all validation is done at runtime and will fail if the type has not property named "Id"; 使用动态和反射(例如,input.GetType()。GetProperty(“ Id”)。GetValue(input))会产生相似的效果,但是1)它不提供编译时保证-所有验证均在运行时完成,并且将失败如果类型没有名为“ Id”的属性; 2) runtime logic has negative impact on performance, which would be visible during intense usage. 2)运行时逻辑会对性能产生负面影响,这在频繁使用时可见。

Inheritance, as suggested by @hofmeister is an option only when you only need to apply this method to types defined by yourself, not any third-party classes. 只有当您只需要将此方法应用于自己定义的类型(而不是任何第三方类)时,@ hofmeister建议的继承是一个选项。

You could use inheritance and implement the Id property for each of your class. 您可以使用继承并为您的每个类实现Id属性。 Something like this: 像这样:

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

In addition to this implementation, you can define a default value (as virtual property) for your base class. 除了此实现之外,您还可以为基类定义默认值(作为虚拟属性)。 As a result, not every class has to override the property Id . 结果,并非每个类都必须重写Id属性。

With this implementation, you can pass the ObjectId as input type to your function and return 0 if it's null . 通过此实现,您可以将ObjectId作为输入类型传递给函数,如果为null ,则返回0

public static int returnId(ObjectId input)
{
    return (input != null) ? input.Id : 0; // input.Id will never be null.
}

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

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