Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 像在C中一样,在TypeScript中一次性传递对象和属性以反映元数据_C#_Typescript_Reflection_Reflect Metadata_Typescript Decorator - Fatal编程技术网

C# 像在C中一样,在TypeScript中一次性传递对象和属性以反映元数据

C# 像在C中一样,在TypeScript中一次性传递对象和属性以反映元数据,c#,typescript,reflection,reflect-metadata,typescript-decorator,C#,Typescript,Reflection,Reflect Metadata,Typescript Decorator,在C中,我们使用DataAnnotation在属性上添加元属性。我需要在ldap模型类的TypeScript中使用此功能。装饰程序应该设置LDAP目录中内部使用的LDAP属性 export class LdapUser { @ldapAttribute('sn') sureName: string; } export function ldapAttribute(attributeName: string): (target: any, propertyKey: string)

在C中,我们使用DataAnnotation在属性上添加元属性。我需要在ldap模型类的TypeScript中使用此功能。装饰程序应该设置LDAP目录中内部使用的LDAP属性

export class LdapUser {
    @ldapAttribute('sn')
    sureName: string;
}

export function ldapAttribute(attributeName: string): (target: any, propertyKey: string) => void {
    return function (target: any, propertyKey: string) {
        Reflect.defineMetadata("ldapAttribute", attributeName, target, propertyKey);
    }
}
但要获取LDAPAttributedCollector值,我需要将对象和属性名称作为原始字符串传递,如下所示:

let user = new LdapUser();
let sureNameAttribute = Reflect.getMetadata("ldapAttribute", user, "sureName"); // sn
let sureNameAttribute = Reflect.getMetadata("ldapAttribute", user.sureName);
它可以工作,但这似乎是一种糟糕的做法,因为在LDAPUserAttribute中重命名sureNameattribute时,如果不将其应用于Reflect.getMetadatacall,则会导致运行时而不是编译器错误。智能感知也缺失了。因此,我正在寻找这样的解决方案:

let user = new LdapUser();
let sureNameAttribute = Reflect.getMetadata("ldapAttribute", user, "sureName"); // sn
let sureNameAttribute = Reflect.getMetadata("ldapAttribute", user.sureName);
这里的问题是,我需要某种反射来划分属性名中的user.sureName,这里是sureName,这里是class object user。我已经在C中使用反射做了类似的事情,但不知道如何在TS中这样做

变通办法 它不如在C中使用反射,但比只使用普通字符串要好:

export function getLdapAttribute<T>(instance: T, attributeName: keyof T) : string {
    let value : string = Reflect.getMetadata("ldapAttribute", instance, attributeName);
    return value;
}

遗憾的是,我们在这里没有智慧。但是如果属性名不存在,至少我们会得到一个编译器错误

我们使用下一种方法来解决这个问题:

export type FieldSpec<TModel, TResult> = ((model?: TModel) => TResult) | string;

export function getFieldName<TModel, TResult>(fieldSpec: FieldSpec<TModel, TResult>): string {
    if (typeof (fieldSpec) == "string" || !fieldSpec) {
        return fieldSpec as string;
    } else {
        var fullFunc = fieldSpec.toString();
        var parts = fullFunc.split(/[.;}]/).filter(x => x.trim().length > 0);
        return parts[parts.length - 1].trim();
    }
}
使用这些帮助程序,您可以编写:

export function getLdapAttribute<T>(instance: T, attributeName: FieldSpec<T,any>) : string {
    let value : string = Reflect.getMetadata("ldapAttribute", instance, getFieldName(attributeName));
    return value;
}

let user = new LdapUser();
let sureNameAttribute = getLdapAttribute(user, () => user.sureName);

问题是?