参考泛型类型的属性?

时间:2011-07-21 22:55:38

标签: c# .net generics variables attributes

我在教自己C#,如果这看起来有点明显,请原谅我。

我正在尝试编写一个泛型函数,我可以将结构数组传递给它,然后使用结构的一个属性。我不知道如何在函数中声明泛型数据类型,我可以按照需要的方式引用属性。

也许我所要求的可以更好地在代码中传达 - 这是一个非工作函数来说明我正在尝试做什么,它如何合乎逻辑地说它应该工作而不知道如何编写它:

public static int AFunctionIsThis<DataType, int DataType.Value>(DataType passedrecord)
{
    temp = passedrecord.Value * 2 + 1;

    return temp;
}

我希望能够在指定要传递的struct的属性时正常调用它。

int NewVariable = AFunctionIsThis<ThisIsAStruct, ThisIsAStruct.AnIntAttribute>(ThisIsADeclaredStruct);

非常感谢,

Hanii Puppy。

4 个答案:

答案 0 :(得分:1)

您不能指定泛型类型应包含的成员,您只能指定通用数据类型。

您将使用定义属性的接口:

public interface IHaveValue {
  int Value { get; }
}

然后您的struct将实现该接口,您可以将接口指定为通用数据类型:

public static int AFunctionIsThis<T>(T passedrecord) where T : IHaveValue {
  return passedrecord.Value * 2 + 1;
}

但是,根据您的使用方法,您根本不需要使用泛型,只需使用界面:

public static int AFunctionIsThis(IHaveValue passedrecord) {
  return passedrecord.Value * 2 + 1;
}

请注意,您很可能根本不使用结构,而是使用类。结构更难以正确实现,所以你应该坚持使用类,直到你有充分的理由使用结构。

答案 1 :(得分:0)

Hanii Puppy:

简而言之,是的,你应该能够做你正在做的事情,但这是一个有效的语法:

public static int AFunctionIsThis<T>(T passedRecord) where T : DataType
{
    var temp = passedRecord.Value;
    return temp;
}

public class DataType
{
    public int Value { get; set; }
}

希望有所帮助。 戴夫

答案 2 :(得分:0)

您要做的是定义一个泛型方法,该方法只接受实现某个接口的T,或者从某个具有名为Value的int成员的基类派生。 e.g:

public interface IClass { int Value{get;set;} }
    public class ExampleImpl : IClass
    {
        int Value{get;set;}
        /* Additional Members\methods here */
    }
    public class HelperClass
    {
    public static int GenMethod<T>(T item) where T:IClass
    {
        return item.Value * 2 + 1;
    }
    }

答案 3 :(得分:0)

(首先,请注意,“属性”一词在.NET中与OOP意义上的含义不同。)

分别使用Converter<T,int>Action<T,int>委托来获取和设置成员。

e.g。

public static int AFunctionIsThis<DataType>(DataType passedrecord, Converter<DataType,int> getter)
{
    temp = getter(passedrecord) * 2 + 1;

    return temp;
}

然后调用它

AFunctionIsThis(ThisIsADeclaredStruct, x => x.AnIntProperty);

如果您还需要设置值,可以使用

AFunctionIsThis(ThisIsADeclaredStruct, x => x.AnIntProperty, (x, v) => { x.AnIntProperty = v; });

或使用Expression<Converter<T>>做一些魔术来抽出成员参考并创建匹配的setter。