我正在尝试使用Generics将结构传递给函数,然后让该函数访问其属性。我想更多地利用泛型,因为它们应该是安全和高效的#34;。这是我的代码的样子。
班级
class foo {
struct A {
int a;
int b
}
struct B {
int a;
int b;
}
}
通用功能
void bar<T> (T input) {
var a = input.a; //this is where its says it know nothing about a
}
函数调用
bar<foo.A> (Aobj);
可以像这样使用泛型吗?(那就是访问对象的数据成员......) 或者我能做的就是创建一个过载的方法?我试图从函数中访问的对象的唯一部分对于这两种类型都是通用的,因此我也认为我可以使用泛型。
答案 0 :(得分:3)
使用泛型并不意味着您可以使用duck typing。 C#是一种静态类型语言,因此您需要执行以下操作:
首先,定义一个定义A
和B
的公共接口的接口:
interface IHasAB
{
int A { get; }
int B { get; }
}
然后,让您的struct
实现此界面:
struct A : IHasAB
{
public A(int a, int b)
{
A = a;
B = b;
}
public int A { get; } // Note: `A` and `B` are now properties, not fields
public int B { get; } // like before; interfaces do not allow you to declare fields.
// Note also: mutable structs are a bad idea! That's why we implement
// `A` and `B` as read-only properties.
}
struct B : IHasAB { … } // same as for `A`
现在,您可以使用其他泛型类型参数约束bar
实现方法where T : IHasAB
:
void bar<T> (T input) where T : IHasAB
{
var a = input.A;
}
T
上的约束使编译器知道它可以期望T
。它现在知道T
是一种实现IHasAB
的类型,因此有两个属性A
和B
(因为这是接口所包含的)。这就是您现在可以.A
访问input
的原因。
请注意,您不一定需要bar
通用:
void bar(IHasAB input)
{
var a = input.A;
}
在后一种情况下,请注意input
现在是引用类型参数。如果您将A
或B
结构中的一个传递给该方法,则必须将其装箱(即从值类型转换为引用类型)。这涉及到一些开销。
我不会进一步探讨可变结构和拳击的危险,这些结构在结构实现接口的情况下很容易发生,因为这完全是另一回事;我建议您花一点时间研究这些主题。 ; - )
答案 1 :(得分:0)
您需要在访问
之类的成员之前将T
强制转换为特定类型
void bar<T> (T input)
{
var obj = T as foo;
if (obj != null)
var a = obj.A;
}
答案 2 :(得分:0)
您需要向编译器指定您期望T的类型。您的方法bar<T>
完全不了解T
,除非必须类型至少类型为object
或object
的子类。这意味着您可以使用object
T
上定义的所有方法。
但是,如果您希望能够使用a
,则需要告诉bar<T>
T
将是一个实现属性a
的类型。接口发挥作用的地方。这意味着您需要创建一个超类或更好的界面,这个界面需要a
的实现,因此您可以告诉bar<T>
T
至少是<your interface>
类型。请参阅以下代码:
interface ImanInterfaceWithA {
int a {get; set;}
}
class foo {
struct A : ImanInterfaceWithA {
public int a {get; set;}
public int b {get; set;}
}
struct B : ImanInterfaceWithA {
public int a {get; set;}
public int b {get; set;}
}
void bar<T> (T input) where T : IamanInterfaceWithA
{
var a = input.a;
}
}
答案 3 :(得分:-1)
使用dynamic
。
void bar<T> (T input) {
dynamic a = input.a; //this is where its says it know nothing about a
}