Referring to attributes in generic types?
I'm teaching myself C#, so forgive me if this seems slig开发者_高级运维htly obvious.
I'm trying to write a generic function that I can pass an array of structs into and then use one of the attributes of the struct. I have no idea how to declare a generic datatype in a function in a way that I can refer to attributes in the way needed.
Maybe what I'm asking can be better communicated in code - this is a non-working function to illustrate what I'm trying to do, how it strikes me as logical that it should work without actually knowing how to write it:
public static int AFunctionIsThis<DataType, int DataType.Value>(DataType passedrecord)
{
temp = passedrecord.Value * 2 + 1;
return temp;
}
And I want to be able to call it normally while specifying the attribute of the struct to be passed.
int NewVariable = AFunctionIsThis<ThisIsAStruct, ThisIsAStruct.AnIntAttribute>(ThisIsADeclaredStruct);
Thankyou very much,
Hanii Puppy.
You can't specify members that a generic type should contain, you can only specify the generic data type.
You would use an interface where the property is defined:
public interface IHaveValue {
int Value { get; }
}
Your struct would then implement the interface, and you can specify the interface as the generic data type:
public static int AFunctionIsThis<T>(T passedrecord) where T : IHaveValue {
return passedrecord.Value * 2 + 1;
}
However, with what you are using it for, you don't need to use generics at all, you can just use the interface:
public static int AFunctionIsThis(IHaveValue passedrecord) {
return passedrecord.Value * 2 + 1;
}
Note that you should most likely not use a struct at all, but a class. A struct is more complicated to implement correctly, so you should stick to classes until you have a really good reason to use a struct.
(To start with, note that the word "attribute" has a different meaning in .NET from the OOP sense.)
Use a Converter<T,int>
and Action<T,int>
delegate to get and set the member, respectively.
e.g.
public static int AFunctionIsThis<DataType>(DataType passedrecord, Converter<DataType,int> getter)
{
temp = getter(passedrecord) * 2 + 1;
return temp;
}
and then call it
AFunctionIsThis(ThisIsADeclaredStruct, x => x.AnIntProperty);
If you also need to set the value, you can use
AFunctionIsThis(ThisIsADeclaredStruct, x => x.AnIntProperty, (x, v) => { x.AnIntProperty = v; });
or do some magic with Expression<Converter<T>>
to yank out the member reference and create a matching setter.
Hanii Puppy:
In short, yes, you should be able to do what you are doing, but here is a syntax that works:
public static int AFunctionIsThis<T>(T passedRecord) where T : DataType
{
var temp = passedRecord.Value;
return temp;
}
public class DataType
{
public int Value { get; set; }
}
Hope that helps. Dave
What you want to do, is define a generic method that accepts only T that implements a certain interface or is derived from certain base class that has an int member called Value. 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;
}
}
精彩评论